split code generator update
authorJürg Billeter <j@bitron.ch>
Thu, 3 May 2007 12:40:17 +0000 (12:40 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Thu, 3 May 2007 12:40:17 +0000 (12:40 +0000)
2007-05-03  Jürg Billeter  <j@bitron.ch>

* gobject/valacodegenerator.vala,
  gobject/valacodegeneratorassignment.vala,
  gobject/valacodegeneratorclass.vala,
  gobject/valacodegeneratorinterface.vala,
  gobject/valacodegeneratorinvocationexpression.vala
  gobject/valacodegeneratormemberaccess.vala,
  gobject/valacodegeneratormethod.vala,
  gobject/valacodegeneratorsignal.vala,
  gobject/valacodegeneratorsourcefile.vala,
  gobject/valacodegeneratorstruct.vala: split code generator
* gobject/Makefile.am, vapigen/Makefile.am: update

svn path=/trunk/; revision=306

13 files changed:
ChangeLog
gobject/Makefile.am
gobject/valacodegenerator.vala
gobject/valacodegeneratorassignment.vala [new file with mode: 0644]
gobject/valacodegeneratorclass.vala [new file with mode: 0644]
gobject/valacodegeneratorinterface.vala [new file with mode: 0644]
gobject/valacodegeneratorinvocationexpression.vala [new file with mode: 0644]
gobject/valacodegeneratormemberaccess.vala [new file with mode: 0644]
gobject/valacodegeneratormethod.vala [new file with mode: 0644]
gobject/valacodegeneratorsignal.vala [new file with mode: 0644]
gobject/valacodegeneratorsourcefile.vala [new file with mode: 0644]
gobject/valacodegeneratorstruct.vala [new file with mode: 0644]
vapigen/Makefile.am

index 02ddfdf..5f801b2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2007-05-03  Jürg Billeter  <j@bitron.ch>
 
+       * gobject/valacodegenerator.vala,
+         gobject/valacodegeneratorassignment.vala,
+         gobject/valacodegeneratorclass.vala,
+         gobject/valacodegeneratorinterface.vala,
+         gobject/valacodegeneratorinvocationexpression.vala
+         gobject/valacodegeneratormemberaccess.vala,
+         gobject/valacodegeneratormethod.vala,
+         gobject/valacodegeneratorsignal.vala,
+         gobject/valacodegeneratorsourcefile.vala, 
+         gobject/valacodegeneratorstruct.vala: split code generator
+       * gobject/Makefile.am, vapigen/Makefile.am: update
+
+2007-05-03  Jürg Billeter  <j@bitron.ch>
+
        * gobject/valacodegenerator.vala: move code generator to new gobject
          directory
        * configure.ac, Makefile.am, vala/Makefile.am, gobject/Makefile.am,
index 3978b17..2101f5e 100644 (file)
@@ -15,12 +15,48 @@ libvala_la_SOURCES = \
        valacodegenerator.c \
        valacodegenerator.h \
        valacodegenerator.vala \
+       valacodegeneratorassignment.c \
+       valacodegeneratorassignment.h \
+       valacodegeneratorassignment.vala \
+       valacodegeneratorclass.c \
+       valacodegeneratorclass.h \
+       valacodegeneratorclass.vala \
+       valacodegeneratorinterface.c \
+       valacodegeneratorinterface.h \
+       valacodegeneratorinterface.vala \
+       valacodegeneratorinvocationexpression.c \
+       valacodegeneratorinvocationexpression.h \
+       valacodegeneratorinvocationexpression.vala \
+       valacodegeneratormemberaccess.c \
+       valacodegeneratormemberaccess.h \
+       valacodegeneratormemberaccess.vala \
+       valacodegeneratormethod.c \
+       valacodegeneratormethod.h \
+       valacodegeneratormethod.vala \
+       valacodegeneratorsignal.c \
+       valacodegeneratorsignal.h \
+       valacodegeneratorsignal.vala \
+       valacodegeneratorsourcefile.c \
+       valacodegeneratorsourcefile.h \
+       valacodegeneratorsourcefile.vala \
+       valacodegeneratorstruct.c \
+       valacodegeneratorstruct.h \
+       valacodegeneratorstruct.vala \
        $(NULL)
 
 gobjectincludedir = $(includedir)/vala-1.0/gobject
 
 gobjectinclude_HEADERS = \
        valacodegenerator.h \
+       valacodegeneratorassignment.h \
+       valacodegeneratorclass.h \
+       valacodegeneratorinterface.h \
+       valacodegeneratorinvocationexpression.h \
+       valacodegeneratormemberaccess.h \
+       valacodegeneratormethod.h \
+       valacodegeneratorsignal.h \
+       valacodegeneratorsourcefile.h \
+       valacodegeneratorstruct.h \
        $(NULL)
 
 gobject.vala gobject.vala.stamp: $(filter %.vala,$(libvala_la_SOURCES))
index f1f0b14..0d0a68b 100644 (file)
@@ -207,864 +207,6 @@ public class Vala.CodeGenerator : CodeVisitor {
                        }
                }
        }
-       
-       private ref CCodeIncludeDirective get_internal_include (string! filename) {
-               return new CCodeIncludeDirective (filename, context.library == null);
-       }
-
-       public override void visit_begin_source_file (SourceFile! source_file) {
-               header_begin = new CCodeFragment ();
-               header_type_declaration = new CCodeFragment ();
-               header_type_definition = new CCodeFragment ();
-               header_type_member_declaration = new CCodeFragment ();
-               source_begin = new CCodeFragment ();
-               source_include_directives = new CCodeFragment ();
-               source_type_member_declaration = new CCodeFragment ();
-               source_type_member_definition = new CCodeFragment ();
-               source_signal_marshaller_definition = new CCodeFragment ();
-               source_signal_marshaller_declaration = new CCodeFragment ();
-               
-               user_marshal_list = new HashTable (str_hash, str_equal);
-               
-               next_temp_var_id = 0;
-               
-               string_h_needed = false;
-               
-               header_begin.append (new CCodeIncludeDirective ("glib.h"));
-               header_begin.append (new CCodeIncludeDirective ("glib-object.h"));
-               source_include_directives.append (new CCodeIncludeDirective (source_file.get_cheader_filename (), true));
-               
-               ref List<weak string> used_includes = null;
-               used_includes.append ("glib.h");
-               used_includes.append ("glib-object.h");
-               used_includes.append (source_file.get_cheader_filename ());
-               
-               foreach (string filename1 in source_file.get_header_external_includes ()) {
-                       if (used_includes.find_custom (filename1, strcmp) == null) {
-                               header_begin.append (new CCodeIncludeDirective (filename1));
-                               used_includes.append (filename1);
-                       }
-               }
-               foreach (string filename2 in source_file.get_header_internal_includes ()) {
-                       if (used_includes.find_custom (filename2, strcmp) == null) {
-                               header_begin.append (get_internal_include (filename2));
-                               used_includes.append (filename2);
-                       }
-               }
-               foreach (string filename3 in source_file.get_source_external_includes ()) {
-                       if (used_includes.find_custom (filename3, strcmp) == null) {
-                               source_include_directives.append (new CCodeIncludeDirective (filename3));
-                               used_includes.append (filename3);
-                       }
-               }
-               foreach (string filename4 in source_file.get_source_internal_includes ()) {
-                       if (used_includes.find_custom (filename4, strcmp) == null) {
-                               source_include_directives.append (get_internal_include (filename4));
-                               used_includes.append (filename4);
-                       }
-               }
-               if (source_file.is_cycle_head) {
-                       foreach (SourceFile cycle_file in source_file.cycle.files) {
-                               var namespaces = cycle_file.get_namespaces ();
-                               foreach (Namespace ns in namespaces) {
-                                       var structs = ns.get_structs ();
-                                       foreach (Struct st in structs) {
-                                               header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (st.get_cname ()), new CCodeVariableDeclarator (st.get_cname ())));
-                                       }
-                                       var classes = ns.get_classes ();
-                                       foreach (Class cl in classes) {
-                                               header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (cl.get_cname ()), new CCodeVariableDeclarator (cl.get_cname ())));
-                                               header_type_declaration.append (new CCodeTypeDefinition ("struct _%sClass".printf (cl.get_cname ()), new CCodeVariableDeclarator ("%sClass".printf (cl.get_cname ()))));
-                                       }
-                                       var ifaces = ns.get_interfaces ();
-                                       foreach (Interface iface in ifaces) {
-                                               header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (iface.get_cname ()), new CCodeVariableDeclarator (iface.get_cname ())));
-                                               header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (iface.get_type_cname ()), new CCodeVariableDeclarator (iface.get_type_cname ())));
-                                       }
-                               }
-                       }
-               }
-               
-               /* generate hardcoded "well-known" macros */
-               source_begin.append (new CCodeMacroReplacement ("VALA_FREE_CHECKED(o,f)", "((o) == NULL ? NULL : ((o) = (f (o), NULL)))"));
-               source_begin.append (new CCodeMacroReplacement ("VALA_FREE_UNCHECKED(o,f)", "((o) = (f (o), NULL))"));
-       }
-       
-       private static ref string get_define_for_filename (string! filename) {
-               var define = new String ("__");
-               
-               var i = filename;
-               while (i.len () > 0) {
-                       var c = i.get_char ();
-                       if (c.isalnum  () && c < 0x80) {
-                               define.append_unichar (c.toupper ());
-                       } else {
-                               define.append_c ('_');
-                       }
-               
-                       i = i.next_char ();
-               }
-               
-               define.append ("__");
-               
-               return define.str;
-       }
-       
-       public override void visit_end_source_file (SourceFile! source_file) {
-               var header_define = get_define_for_filename (source_file.get_cheader_filename ());
-               
-               if (string_h_needed) {
-                       source_include_directives.append (new CCodeIncludeDirective ("string.h"));
-               }
-               
-               CCodeComment comment = null;
-               if (source_file.comment != null) {
-                       comment = new CCodeComment (source_file.comment);
-               }
-
-               var writer = new CCodeWriter (source_file.get_cheader_filename ());
-               if (comment != null) {
-                       comment.write (writer);
-               }
-               writer.write_newline ();
-               var once = new CCodeOnceSection (header_define);
-               once.append (new CCodeNewline ());
-               once.append (header_begin);
-               once.append (new CCodeNewline ());
-               once.append (new CCodeIdentifier ("G_BEGIN_DECLS"));
-               once.append (new CCodeNewline ());
-               once.append (new CCodeNewline ());
-               once.append (header_type_declaration);
-               once.append (new CCodeNewline ());
-               once.append (header_type_definition);
-               once.append (new CCodeNewline ());
-               once.append (header_type_member_declaration);
-               once.append (new CCodeNewline ());
-               once.append (new CCodeIdentifier ("G_END_DECLS"));
-               once.append (new CCodeNewline ());
-               once.append (new CCodeNewline ());
-               once.write (writer);
-               writer.close ();
-               
-               writer = new CCodeWriter (source_file.get_csource_filename ());
-               if (comment != null) {
-                       comment.write (writer);
-               }
-               source_begin.write (writer);
-               writer.write_newline ();
-               source_include_directives.write (writer);
-               writer.write_newline ();
-               source_type_member_declaration.write (writer);
-               writer.write_newline ();
-               source_signal_marshaller_declaration.write (writer);
-               writer.write_newline ();
-               source_type_member_definition.write (writer);
-               writer.write_newline ();
-               source_signal_marshaller_definition.write (writer);
-               writer.write_newline ();
-               writer.close ();
-
-               header_begin = null;
-               header_type_declaration = null;
-               header_type_definition = null;
-               header_type_member_declaration = null;
-               source_begin = null;
-               source_include_directives = null;
-               source_type_member_declaration = null;
-               source_type_member_definition = null;
-               source_signal_marshaller_definition = null;
-               source_signal_marshaller_declaration = null;
-       }
-
-       public override void visit_begin_class (Class! cl) {
-               current_symbol = cl.symbol;
-               current_type_symbol = cl.symbol;
-               current_class = cl;
-
-               if (cl.is_static) {
-                       return;
-               }
-
-               instance_struct = new CCodeStruct ("_%s".printf (cl.get_cname ()));
-               type_struct = new CCodeStruct ("_%sClass".printf (cl.get_cname ()));
-               instance_priv_struct = new CCodeStruct ("_%sPrivate".printf (cl.get_cname ()));
-               prop_enum = new CCodeEnum ();
-               prop_enum.add_value ("%s_DUMMY_PROPERTY".printf (cl.get_upper_case_cname (null)), null);
-               instance_init_fragment = new CCodeFragment ();
-               instance_dispose_fragment = new CCodeFragment ();
-               
-               
-               header_type_declaration.append (new CCodeNewline ());
-               var macro = "(%s_get_type ())".printf (cl.get_lower_case_cname (null));
-               header_type_declaration.append (new CCodeMacroReplacement (cl.get_upper_case_cname ("TYPE_"), macro));
-
-               macro = "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
-               header_type_declaration.append (new CCodeMacroReplacement ("%s(obj)".printf (cl.get_upper_case_cname (null)), macro));
-
-               macro = "(G_TYPE_CHECK_CLASS_CAST ((klass), %s, %sClass))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
-               header_type_declaration.append (new CCodeMacroReplacement ("%s_CLASS(klass)".printf (cl.get_upper_case_cname (null)), macro));
-
-               macro = "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (cl.get_upper_case_cname ("TYPE_"));
-               header_type_declaration.append (new CCodeMacroReplacement ("%s(obj)".printf (cl.get_upper_case_cname ("IS_")), macro));
-
-               macro = "(G_TYPE_CHECK_CLASS_TYPE ((klass), %s))".printf (cl.get_upper_case_cname ("TYPE_"));
-               header_type_declaration.append (new CCodeMacroReplacement ("%s_CLASS(klass)".printf (cl.get_upper_case_cname ("IS_")), macro));
-
-               macro = "(G_TYPE_INSTANCE_GET_CLASS ((obj), %s, %sClass))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
-               header_type_declaration.append (new CCodeMacroReplacement ("%s_GET_CLASS(obj)".printf (cl.get_upper_case_cname (null)), macro));
-               header_type_declaration.append (new CCodeNewline ());
-
-
-               if (cl.source_reference.file.cycle == null) {
-                       header_type_declaration.append (new CCodeTypeDefinition ("struct %s".printf (instance_struct.name), new CCodeVariableDeclarator (cl.get_cname ())));
-                       header_type_declaration.append (new CCodeTypeDefinition ("struct %s".printf (type_struct.name), new CCodeVariableDeclarator ("%sClass".printf (cl.get_cname ()))));
-               }
-               header_type_declaration.append (new CCodeTypeDefinition ("struct %s".printf (instance_priv_struct.name), new CCodeVariableDeclarator ("%sPrivate".printf (cl.get_cname ()))));
-               
-               instance_struct.add_field (cl.base_class.get_cname (), "parent");
-               instance_struct.add_field ("%sPrivate *".printf (cl.get_cname ()), "priv");
-               type_struct.add_field ("%sClass".printf (cl.base_class.get_cname ()), "parent");
-
-               if (cl.source_reference.comment != null) {
-                       header_type_definition.append (new CCodeComment (cl.source_reference.comment));
-               }
-               header_type_definition.append (instance_struct);
-               header_type_definition.append (type_struct);
-               source_type_member_declaration.append (instance_priv_struct);
-               macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
-               source_type_member_declaration.append (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), macro));
-               source_type_member_declaration.append (prop_enum);
-       }
-       
-       public override void visit_end_class (Class! cl) {
-               if (!cl.is_static) {
-                       add_get_property_function (cl);
-                       add_set_property_function (cl);
-                       add_class_init_function (cl);
-                       
-                       foreach (TypeReference base_type in cl.get_base_types ()) {
-                               if (base_type.data_type is Interface) {
-                                       add_interface_init_function (cl, (Interface) base_type.data_type);
-                               }
-                       }
-                       
-                       add_instance_init_function (cl);
-                       if (memory_management && cl.get_fields () != null) {
-                               add_dispose_function (cl);
-                       }
-                       
-                       var type_fun = new ClassRegisterFunction (cl);
-                       type_fun.init_from_type (in_plugin);
-                       header_type_member_declaration.append (type_fun.get_declaration ());
-                       source_type_member_definition.append (type_fun.get_definition ());
-                       
-                       if (in_plugin) {
-                               // FIXME resolve potential dependency issues, i.e. base types have to be registered before derived types
-                               var register_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_register_type".printf (cl.get_lower_case_cname (null))));
-                               register_call.add_argument (new CCodeIdentifier (module_init_param_name));
-                               module_init_fragment.append (new CCodeExpressionStatement (register_call));
-                       }
-               }
-
-               current_type_symbol = null;
-               current_class = null;
-               instance_dispose_fragment = null;
-       }
-       
-       private void add_class_init_function (Class! cl) {
-               var class_init = new CCodeFunction ("%s_class_init".printf (cl.get_lower_case_cname (null)), "void");
-               class_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
-               class_init.modifiers = CCodeModifiers.STATIC;
-               
-               var init_block = new CCodeBlock ();
-               class_init.block = init_block;
-               
-               ref CCodeFunctionCall ccall;
-               
-               /* save pointer to parent class */
-               var parent_decl = new CCodeDeclaration ("gpointer");
-               var parent_var_decl = new CCodeVariableDeclarator ("%s_parent_class".printf (cl.get_lower_case_cname (null)));
-               parent_var_decl.initializer = new CCodeConstant ("NULL");
-               parent_decl.add_declarator (parent_var_decl);
-               parent_decl.modifiers = CCodeModifiers.STATIC;
-               source_type_member_declaration.append (parent_decl);
-               ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek_parent"));
-               ccall.add_argument (new CCodeIdentifier ("klass"));
-               var parent_assignment = new CCodeAssignment (new CCodeIdentifier ("%s_parent_class".printf (cl.get_lower_case_cname (null))), ccall);
-               init_block.add_statement (new CCodeExpressionStatement (parent_assignment));
-               
-               /* add struct for private fields */
-               if (cl.has_private_fields) {
-                       ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_add_private"));
-                       ccall.add_argument (new CCodeIdentifier ("klass"));
-                       ccall.add_argument (new CCodeConstant ("sizeof (%sPrivate)".printf (cl.get_cname ())));
-                       init_block.add_statement (new CCodeExpressionStatement (ccall));
-               }
-               
-               /* set property handlers */
-               ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
-               ccall.add_argument (new CCodeIdentifier ("klass"));
-               init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "get_property"), new CCodeIdentifier ("%s_get_property".printf (cl.get_lower_case_cname (null))))));
-               init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "set_property"), new CCodeIdentifier ("%s_set_property".printf (cl.get_lower_case_cname (null))))));
-               
-               /* set constructor */
-               if (cl.constructor != null) {
-                       var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
-                       ccast.add_argument (new CCodeIdentifier ("klass"));
-                       init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "constructor"), new CCodeIdentifier ("%s_constructor".printf (cl.get_lower_case_cname (null))))));
-               }
-
-               /* set dispose function */
-               if (memory_management && cl.get_fields () != null) {
-                       var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
-                       ccast.add_argument (new CCodeIdentifier ("klass"));
-                       init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "dispose"), new CCodeIdentifier ("%s_dispose".printf (cl.get_lower_case_cname (null))))));
-               }
-               
-               /* connect overridden methods */
-               var methods = cl.get_methods ();
-               foreach (Method m in methods) {
-                       if (m.base_method == null) {
-                               continue;
-                       }
-                       var base_type = m.base_method.symbol.parent_symbol.node;
-                       
-                       var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (((Class) base_type).get_upper_case_cname (null))));
-                       ccast.add_argument (new CCodeIdentifier ("klass"));
-                       init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, m.name), new CCodeIdentifier (m.get_real_cname ()))));
-               }
-
-               /* create destroy_func properties for generic types */
-               foreach (TypeParameter type_param in cl.get_type_parameters ()) {
-                       string func_name = "%s_destroy_func".printf (type_param.name.down ());
-                       var func_name_constant = new CCodeConstant ("\"%s-destroy-func\"".printf (type_param.name.down ()));
-                       string enum_value = "%s_%s".printf (cl.get_lower_case_cname (null), func_name).up ();
-                       var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_install_property"));
-                       cinst.add_argument (ccall);
-                       cinst.add_argument (new CCodeConstant (enum_value));
-                       var cspec = new CCodeFunctionCall (new CCodeIdentifier ("g_param_spec_pointer"));
-                       cspec.add_argument (func_name_constant);
-                       cspec.add_argument (new CCodeConstant ("\"destroy func\""));
-                       cspec.add_argument (new CCodeConstant ("\"destroy func\""));
-                       cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY"));
-                       cinst.add_argument (cspec);
-                       init_block.add_statement (new CCodeExpressionStatement (cinst));
-                       prop_enum.add_value (enum_value, null);
-
-                       instance_priv_struct.add_field ("GDestroyNotify", func_name);
-               }
-
-               /* create properties */
-               var props = cl.get_properties ();
-               foreach (Property prop in props) {
-                       if (prop.overrides || prop.base_interface_property != null) {
-                               var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_override_property"));
-                               cinst.add_argument (ccall);
-                               cinst.add_argument (new CCodeConstant (prop.get_upper_case_cname ()));
-                               cinst.add_argument (prop.get_canonical_cconstant ());
-                               
-                               init_block.add_statement (new CCodeExpressionStatement (cinst));
-                       } else {
-                               var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_install_property"));
-                               cinst.add_argument (ccall);
-                               cinst.add_argument (new CCodeConstant (prop.get_upper_case_cname ()));
-                               cinst.add_argument (get_param_spec (prop));
-                               
-                               init_block.add_statement (new CCodeExpressionStatement (cinst));
-                       }
-               }
-               
-               /* create signals */
-               foreach (Signal sig in cl.get_signals ()) {
-                       init_block.add_statement (new CCodeExpressionStatement (get_signal_creation (sig, cl)));
-               }
-               
-               source_type_member_definition.append (class_init);
-       }
-       
-       private void add_interface_init_function (Class! cl, Interface! iface) {
-               var iface_init = new CCodeFunction ("%s_%s_interface_init".printf (cl.get_lower_case_cname (null), iface.get_lower_case_cname (null)), "void");
-               iface_init.add_parameter (new CCodeFormalParameter ("iface", "%s *".printf (iface.get_type_cname ())));
-               iface_init.modifiers = CCodeModifiers.STATIC;
-               
-               var init_block = new CCodeBlock ();
-               iface_init.block = init_block;
-               
-               ref CCodeFunctionCall ccall;
-               
-               /* save pointer to parent vtable */
-               string parent_iface_var = "%s_%s_parent_iface".printf (cl.get_lower_case_cname (null), iface.get_lower_case_cname (null));
-               var parent_decl = new CCodeDeclaration (iface.get_type_cname () + "*");
-               var parent_var_decl = new CCodeVariableDeclarator (parent_iface_var);
-               parent_var_decl.initializer = new CCodeConstant ("NULL");
-               parent_decl.add_declarator (parent_var_decl);
-               parent_decl.modifiers = CCodeModifiers.STATIC;
-               source_type_member_declaration.append (parent_decl);
-               ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_interface_peek_parent"));
-               ccall.add_argument (new CCodeIdentifier ("iface"));
-               var parent_assignment = new CCodeAssignment (new CCodeIdentifier (parent_iface_var), ccall);
-               init_block.add_statement (new CCodeExpressionStatement (parent_assignment));
-
-               var methods = cl.get_methods ();
-               foreach (Method m in methods) {
-                       if (m.base_interface_method == null) {
-                               continue;
-                       }
-
-                       var base_type = m.base_interface_method.symbol.parent_symbol.node;
-                       if (base_type != iface) {
-                               continue;
-                       }
-                       
-                       var ciface = new CCodeIdentifier ("iface");
-                       init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ciface, m.name), new CCodeIdentifier (m.get_real_cname ()))));
-               }
-               
-               source_type_member_definition.append (iface_init);
-       }
-       
-       private void add_instance_init_function (Class! cl) {
-               var instance_init = new CCodeFunction ("%s_init".printf (cl.get_lower_case_cname (null)), "void");
-               instance_init.add_parameter (new CCodeFormalParameter ("self", "%s *".printf (cl.get_cname ())));
-               instance_init.modifiers = CCodeModifiers.STATIC;
-               
-               var init_block = new CCodeBlock ();
-               instance_init.block = init_block;
-               
-               if (cl.has_private_fields) {
-                       var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (cl.get_upper_case_cname (null))));
-                       ccall.add_argument (new CCodeIdentifier ("self"));
-                       init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), ccall)));
-               }
-               
-               init_block.add_statement (instance_init_fragment);
-               
-               var init_sym = cl.symbol.lookup ("init");
-               if (init_sym != null) {
-                       var init_fun = (Method) init_sym.node;
-                       init_block.add_statement (init_fun.body.ccodenode);
-               }
-               
-               source_type_member_definition.append (instance_init);
-       }
-       
-       private void add_dispose_function (Class! cl) {
-               function = new CCodeFunction ("%s_dispose".printf (cl.get_lower_case_cname (null)), "void");
-               function.modifiers = CCodeModifiers.STATIC;
-               
-               function.add_parameter (new CCodeFormalParameter ("obj", "GObject *"));
-               
-               source_type_member_declaration.append (function.copy ());
-
-
-               var cblock = new CCodeBlock ();
-
-               var ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null)));
-               ccall.add_argument (new CCodeIdentifier ("obj"));
-               
-               var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
-               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
-               
-               cblock.add_statement (cdecl);
-               
-               cblock.add_statement (instance_dispose_fragment);
-
-               cdecl = new CCodeDeclaration ("%sClass *".printf (cl.get_cname ()));
-               cdecl.add_declarator (new CCodeVariableDeclarator ("klass"));
-               cblock.add_statement (cdecl);
-
-               cdecl = new CCodeDeclaration ("GObjectClass *");
-               cdecl.add_declarator (new CCodeVariableDeclarator ("parent_class"));
-               cblock.add_statement (cdecl);
-
-
-               ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek"));
-               ccall.add_argument (new CCodeIdentifier (cl.get_upper_case_cname ("TYPE_")));
-               var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (cl.get_upper_case_cname (null))));
-               ccast.add_argument (ccall);
-               cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("klass"), ccast)));
-
-               ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek_parent"));
-               ccall.add_argument (new CCodeIdentifier ("klass"));
-               ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
-               ccast.add_argument (ccall);
-               cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_class"), ccast)));
-
-               
-               ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (new CCodeIdentifier ("parent_class"), "dispose"));
-               ccall.add_argument (new CCodeIdentifier ("obj"));
-               cblock.add_statement (new CCodeExpressionStatement (ccall));
-
-
-               function.block = cblock;
-
-               source_type_member_definition.append (function);
-       }
-       
-       private ref CCodeIdentifier! get_value_setter_function (TypeReference! type_reference) {
-               if (type_reference.data_type is Class || type_reference.data_type is Interface) {
-                       return new CCodeIdentifier ("g_value_set_object");
-               } else if (type_reference.data_type == string_type.data_type) {
-                       return new CCodeIdentifier ("g_value_set_string");
-               } else if (type_reference.data_type == int_type.data_type
-                          || type_reference.data_type is Enum) {
-                       return new CCodeIdentifier ("g_value_set_int");
-               } else if (type_reference.data_type == uint_type.data_type) {
-                       return new CCodeIdentifier ("g_value_set_uint");
-               } else if (type_reference.data_type == long_type.data_type) {
-                       return new CCodeIdentifier ("g_value_set_long");
-               } else if (type_reference.data_type == ulong_type.data_type) {
-                       return new CCodeIdentifier ("g_value_set_ulong");
-               } else if (type_reference.data_type == bool_type.data_type) {
-                       return new CCodeIdentifier ("g_value_set_boolean");
-               } else if (type_reference.data_type == float_type.data_type) {
-                       return new CCodeIdentifier ("g_value_set_float");
-               } else if (type_reference.data_type == double_type.data_type) {
-                       return new CCodeIdentifier ("g_value_set_double");
-               } else {
-                       return new CCodeIdentifier ("g_value_set_pointer");
-               }
-       }
-       
-       private void add_get_property_function (Class! cl) {
-               var get_prop = new CCodeFunction ("%s_get_property".printf (cl.get_lower_case_cname (null)), "void");
-               get_prop.modifiers = CCodeModifiers.STATIC;
-               get_prop.add_parameter (new CCodeFormalParameter ("object", "GObject *"));
-               get_prop.add_parameter (new CCodeFormalParameter ("property_id", "guint"));
-               get_prop.add_parameter (new CCodeFormalParameter ("value", "GValue *"));
-               get_prop.add_parameter (new CCodeFormalParameter ("pspec", "GParamSpec *"));
-               
-               var block = new CCodeBlock ();
-               
-               var ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null)));
-               ccall.add_argument (new CCodeIdentifier ("object"));
-               var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
-               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
-               block.add_statement (cdecl);
-               
-               var cswitch = new CCodeSwitchStatement (new CCodeIdentifier ("property_id"));
-               var props = cl.get_properties ();
-               foreach (Property prop in props) {
-                       if (prop.get_accessor == null || prop.is_abstract) {
-                               continue;
-                       }
-
-                       bool is_virtual = prop.base_property != null || prop.base_interface_property != null;
-
-                       string prefix = cl.get_lower_case_cname (null);
-                       if (is_virtual) {
-                               prefix += "_real";
-                       }
-
-                       var ccase = new CCodeCaseStatement (new CCodeIdentifier (prop.get_upper_case_cname ()));
-                       var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_get_%s".printf (prefix, prop.name)));
-                       ccall.add_argument (new CCodeIdentifier ("self"));
-                       var csetcall = new CCodeFunctionCall ();
-                       csetcall.call = get_value_setter_function (prop.type_reference);
-                       csetcall.add_argument (new CCodeIdentifier ("value"));
-                       csetcall.add_argument (ccall);
-                       ccase.add_statement (new CCodeExpressionStatement (csetcall));
-                       ccase.add_statement (new CCodeBreakStatement ());
-                       cswitch.add_case (ccase);
-               }
-               block.add_statement (cswitch);
-
-               get_prop.block = block;
-               
-               source_type_member_definition.append (get_prop);
-       }
-       
-       private void add_set_property_function (Class! cl) {
-               var set_prop = new CCodeFunction ("%s_set_property".printf (cl.get_lower_case_cname (null)), "void");
-               set_prop.modifiers = CCodeModifiers.STATIC;
-               set_prop.add_parameter (new CCodeFormalParameter ("object", "GObject *"));
-               set_prop.add_parameter (new CCodeFormalParameter ("property_id", "guint"));
-               set_prop.add_parameter (new CCodeFormalParameter ("value", "const GValue *"));
-               set_prop.add_parameter (new CCodeFormalParameter ("pspec", "GParamSpec *"));
-               
-               var block = new CCodeBlock ();
-               
-               var ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null)));
-               ccall.add_argument (new CCodeIdentifier ("object"));
-               var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
-               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
-               block.add_statement (cdecl);
-               
-               var cswitch = new CCodeSwitchStatement (new CCodeIdentifier ("property_id"));
-               var props = cl.get_properties ();
-               foreach (Property prop in props) {
-                       if (prop.set_accessor == null || prop.is_abstract) {
-                               continue;
-                       }
-
-                       bool is_virtual = prop.base_property != null || prop.base_interface_property != null;
-
-                       string prefix = cl.get_lower_case_cname (null);
-                       if (is_virtual) {
-                               prefix += "_real";
-                       }
-
-                       var ccase = new CCodeCaseStatement (new CCodeIdentifier (prop.get_upper_case_cname ()));
-                       var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_set_%s".printf (prefix, prop.name)));
-                       ccall.add_argument (new CCodeIdentifier ("self"));
-                       var cgetcall = new CCodeFunctionCall ();
-                       if (prop.type_reference.data_type is Class || prop.type_reference.data_type is Interface) {
-                               cgetcall.call = new CCodeIdentifier ("g_value_get_object");
-                       } else if (prop.type_reference.type_name == "string") {
-                               cgetcall.call = new CCodeIdentifier ("g_value_get_string");
-                       } else if (prop.type_reference.type_name == "int" || prop.type_reference.data_type is Enum) {
-                               cgetcall.call = new CCodeIdentifier ("g_value_get_int");
-                       } else if (prop.type_reference.type_name == "uint") {
-                               cgetcall.call = new CCodeIdentifier ("g_value_get_uint");
-                       } else if (prop.type_reference.type_name == "long") {
-                               cgetcall.call = new CCodeIdentifier ("g_value_get_long");
-                       } else if (prop.type_reference.type_name == "ulong") {
-                               cgetcall.call = new CCodeIdentifier ("g_value_get_ulong");
-                       } else if (prop.type_reference.type_name == "bool") {
-                               cgetcall.call = new CCodeIdentifier ("g_value_get_boolean");
-                       } else if (prop.type_reference.type_name == "float") {
-                               cgetcall.call = new CCodeIdentifier ("g_value_get_float");
-                       } else if (prop.type_reference.type_name == "double") {
-                               cgetcall.call = new CCodeIdentifier ("g_value_get_double");
-                       } else {
-                               cgetcall.call = new CCodeIdentifier ("g_value_get_pointer");
-                       }
-                       cgetcall.add_argument (new CCodeIdentifier ("value"));
-                       ccall.add_argument (cgetcall);
-                       ccase.add_statement (new CCodeExpressionStatement (ccall));
-                       ccase.add_statement (new CCodeBreakStatement ());
-                       cswitch.add_case (ccase);
-               }
-               block.add_statement (cswitch);
-
-               /* destroy func properties for generic types */
-               foreach (TypeParameter type_param in cl.get_type_parameters ()) {
-                       string func_name = "%s_destroy_func".printf (type_param.name.down ());
-                       string enum_value = "%s_%s".printf (cl.get_lower_case_cname (null), func_name).up ();
-
-                       var ccase = new CCodeCaseStatement (new CCodeIdentifier (enum_value));
-                       var cfield = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name);
-                       var cgetcall = new CCodeFunctionCall (new CCodeIdentifier ("g_value_get_pointer"));
-                       cgetcall.add_argument (new CCodeIdentifier ("value"));
-                       ccase.add_statement (new CCodeExpressionStatement (new CCodeAssignment (cfield, cgetcall)));
-                       ccase.add_statement (new CCodeBreakStatement ());
-                       cswitch.add_case (ccase);
-               }
-
-               set_prop.block = block;
-               
-               source_type_member_definition.append (set_prop);
-       }
-       
-       public override void visit_begin_struct (Struct! st) {
-               current_type_symbol = st.symbol;
-
-               instance_struct = new CCodeStruct ("_%s".printf (st.get_cname ()));
-
-               if (st.source_reference.file.cycle == null) {
-                       header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (st.get_cname ()), new CCodeVariableDeclarator (st.get_cname ())));
-               }
-
-               if (st.source_reference.comment != null) {
-                       header_type_definition.append (new CCodeComment (st.source_reference.comment));
-               }
-               header_type_definition.append (instance_struct);
-       }
-       
-       public override void visit_end_struct (Struct! st) {
-               current_type_symbol = null;
-       }
-
-       public override void visit_begin_interface (Interface! iface) {
-               current_symbol = iface.symbol;
-               current_type_symbol = iface.symbol;
-
-               if (iface.is_static) {
-                       return;
-               }
-
-               type_struct = new CCodeStruct ("_%s".printf (iface.get_type_cname ()));
-               
-               header_type_declaration.append (new CCodeNewline ());
-               var macro = "(%s_get_type ())".printf (iface.get_lower_case_cname (null));
-               header_type_declaration.append (new CCodeMacroReplacement (iface.get_upper_case_cname ("TYPE_"), macro));
-
-               macro = "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (iface.get_upper_case_cname ("TYPE_"), iface.get_cname ());
-               header_type_declaration.append (new CCodeMacroReplacement ("%s(obj)".printf (iface.get_upper_case_cname (null)), macro));
-
-               macro = "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (iface.get_upper_case_cname ("TYPE_"));
-               header_type_declaration.append (new CCodeMacroReplacement ("%s(obj)".printf (iface.get_upper_case_cname ("IS_")), macro));
-
-               macro = "(G_TYPE_INSTANCE_GET_INTERFACE ((obj), %s, %s))".printf (iface.get_upper_case_cname ("TYPE_"), iface.get_type_cname ());
-               header_type_declaration.append (new CCodeMacroReplacement ("%s_GET_INTERFACE(obj)".printf (iface.get_upper_case_cname (null)), macro));
-               header_type_declaration.append (new CCodeNewline ());
-
-
-               if (iface.source_reference.file.cycle == null) {
-                       header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (iface.get_cname ()), new CCodeVariableDeclarator (iface.get_cname ())));
-                       header_type_declaration.append (new CCodeTypeDefinition ("struct %s".printf (type_struct.name), new CCodeVariableDeclarator (iface.get_type_cname ())));
-               }
-               
-               type_struct.add_field ("GTypeInterface", "parent");
-
-               if (iface.source_reference.comment != null) {
-                       header_type_definition.append (new CCodeComment (iface.source_reference.comment));
-               }
-               header_type_definition.append (type_struct);
-       }
-
-       public override void visit_end_interface (Interface! iface) {
-               if (!iface.is_static) {
-                       add_interface_base_init_function (iface);
-
-                       var type_fun = new InterfaceRegisterFunction (iface);
-                       type_fun.init_from_type ();
-                       header_type_member_declaration.append (type_fun.get_declaration ());
-                       source_type_member_definition.append (type_fun.get_definition ());
-               }
-
-               current_type_symbol = null;
-       }
-       
-       private ref CCodeFunctionCall! get_param_spec (Property! prop) {
-               var cspec = new CCodeFunctionCall ();
-               cspec.add_argument (prop.get_canonical_cconstant ());
-               cspec.add_argument (new CCodeConstant ("\"foo\""));
-               cspec.add_argument (new CCodeConstant ("\"bar\""));
-               if (prop.type_reference.data_type is Class || prop.type_reference.data_type is Interface) {
-                       cspec.call = new CCodeIdentifier ("g_param_spec_object");
-                       cspec.add_argument (new CCodeIdentifier (prop.type_reference.data_type.get_upper_case_cname ("TYPE_")));
-               } else if (prop.type_reference.data_type == string_type.data_type) {
-                       cspec.call = new CCodeIdentifier ("g_param_spec_string");
-                       cspec.add_argument (new CCodeConstant ("NULL"));
-               } else if (prop.type_reference.data_type == int_type.data_type
-                          || prop.type_reference.data_type is Enum) {
-                       cspec.call = new CCodeIdentifier ("g_param_spec_int");
-                       cspec.add_argument (new CCodeConstant ("G_MININT"));
-                       cspec.add_argument (new CCodeConstant ("G_MAXINT"));
-                       cspec.add_argument (new CCodeConstant ("0"));
-               } else if (prop.type_reference.data_type == uint_type.data_type) {
-                       cspec.call = new CCodeIdentifier ("g_param_spec_uint");
-                       cspec.add_argument (new CCodeConstant ("0"));
-                       cspec.add_argument (new CCodeConstant ("G_MAXUINT"));
-                       cspec.add_argument (new CCodeConstant ("0U"));
-               } else if (prop.type_reference.data_type == long_type.data_type) {
-                       cspec.call = new CCodeIdentifier ("g_param_spec_long");
-                       cspec.add_argument (new CCodeConstant ("G_MINLONG"));
-                       cspec.add_argument (new CCodeConstant ("G_MAXLONG"));
-                       cspec.add_argument (new CCodeConstant ("0L"));
-               } else if (prop.type_reference.data_type == ulong_type.data_type) {
-                       cspec.call = new CCodeIdentifier ("g_param_spec_ulong");
-                       cspec.add_argument (new CCodeConstant ("0"));
-                       cspec.add_argument (new CCodeConstant ("G_MAXULONG"));
-                       cspec.add_argument (new CCodeConstant ("0UL"));
-               } else if (prop.type_reference.data_type == bool_type.data_type) {
-                       cspec.call = new CCodeIdentifier ("g_param_spec_boolean");
-                       cspec.add_argument (new CCodeConstant ("FALSE"));
-               } else if (prop.type_reference.data_type == float_type.data_type) {
-                       cspec.call = new CCodeIdentifier ("g_param_spec_float");
-                       cspec.add_argument (new CCodeConstant ("-G_MAXFLOAT"));
-                       cspec.add_argument (new CCodeConstant ("G_MAXFLOAT"));
-                       cspec.add_argument (new CCodeConstant ("0.0F"));
-               } else if (prop.type_reference.data_type == double_type.data_type) {
-                       cspec.call = new CCodeIdentifier ("g_param_spec_double");
-                       cspec.add_argument (new CCodeConstant ("-G_MAXDOUBLE"));
-                       cspec.add_argument (new CCodeConstant ("G_MAXDOUBLE"));
-                       cspec.add_argument (new CCodeConstant ("0.0"));
-               } else {
-                       cspec.call = new CCodeIdentifier ("g_param_spec_pointer");
-               }
-               
-               var pflags = "G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB";
-               if (prop.get_accessor != null) {
-                       pflags = "%s%s".printf (pflags, " | G_PARAM_READABLE");
-               }
-               if (prop.set_accessor != null) {
-                       pflags = "%s%s".printf (pflags, " | G_PARAM_WRITABLE");
-                       if (prop.set_accessor.construction) {
-                               if (prop.set_accessor.writable) {
-                                       pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT");
-                               } else {
-                                       pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT_ONLY");
-                               }
-                       }
-               }
-               cspec.add_argument (new CCodeConstant (pflags));
-
-               return cspec;
-       }
-
-       private ref CCodeFunctionCall! get_signal_creation (Signal! sig, DataType! type) {      
-               var csignew = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_new"));
-               csignew.add_argument (new CCodeConstant ("\"%s\"".printf (sig.name)));
-               csignew.add_argument (new CCodeIdentifier (type.get_upper_case_cname ("TYPE_")));
-               csignew.add_argument (new CCodeConstant ("G_SIGNAL_RUN_LAST"));
-               csignew.add_argument (new CCodeConstant ("0"));
-               csignew.add_argument (new CCodeConstant ("NULL"));
-               csignew.add_argument (new CCodeConstant ("NULL"));
-
-               string marshaller = get_signal_marshaller_function (sig);
-
-               var marshal_arg = new CCodeIdentifier (marshaller);
-               csignew.add_argument (marshal_arg);
-
-               var params = sig.get_parameters ();
-               var params_len = params.length ();
-               if (sig.return_type.type_parameter != null) {
-                       csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
-               } else if (sig.return_type.data_type == null) {
-                       csignew.add_argument (new CCodeConstant ("G_TYPE_NONE"));
-               } else {
-                       csignew.add_argument (new CCodeConstant (sig.return_type.data_type.get_type_id ()));
-               }
-               csignew.add_argument (new CCodeConstant ("%d".printf (params_len)));
-               foreach (FormalParameter param in params) {
-                       if (param.type_reference.type_parameter != null) {
-                               csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
-                       } else {
-                               csignew.add_argument (new CCodeConstant (param.type_reference.data_type.get_type_id ()));
-                       }
-               }
-
-               marshal_arg.name = marshaller;
-
-               return csignew;
-       }
-
-       private void add_interface_base_init_function (Interface! iface) {
-               var base_init = new CCodeFunction ("%s_base_init".printf (iface.get_lower_case_cname (null)), "void");
-               base_init.add_parameter (new CCodeFormalParameter ("iface", "%sIface *".printf (iface.get_cname ())));
-               base_init.modifiers = CCodeModifiers.STATIC;
-               
-               var init_block = new CCodeBlock ();
-               
-               /* make sure not to run the initialization code twice */
-               base_init.block = new CCodeBlock ();
-               var decl = new CCodeDeclaration (bool_type.get_cname ());
-               decl.modifiers |= CCodeModifiers.STATIC;
-               decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("initialized", new CCodeConstant ("FALSE")));
-               base_init.block.add_statement (decl);
-               var cif = new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("initialized")), init_block);
-               base_init.block.add_statement (cif);
-               init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("initialized"), new CCodeConstant ("TRUE"))));
-               
-               /* create properties */
-               var props = iface.get_properties ();
-               foreach (Property prop in props) {
-                       var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_interface_install_property"));
-                       cinst.add_argument (new CCodeIdentifier ("iface"));
-                       cinst.add_argument (get_param_spec (prop));
-
-                       init_block.add_statement (new CCodeExpressionStatement (cinst));
-               }
-               
-               /* create signals */
-               foreach (Signal sig in iface.get_signals ()) {
-                       init_block.add_statement (new CCodeExpressionStatement (get_signal_creation (sig, iface)));
-               }
-               
-               source_type_member_definition.append (base_init);
-       }
 
        public override void visit_begin_enum (Enum! en) {
                cenum = new CCodeEnum (en.get_cname ());
@@ -1185,479 +327,49 @@ public class Vala.CodeGenerator : CodeVisitor {
                                        var var_decl = new CCodeVariableDeclarator (f.get_cname ());
                                        if (f.initializer != null) {
                                                var_decl.initializer = (CCodeExpression) f.initializer.ccodenode;
-                                       }
-                                       cdecl.add_declarator (var_decl);
-                                       cdecl.modifiers = CCodeModifiers.STATIC;
-                                       source_type_member_declaration.append (cdecl);
-                               }
-                       }
-               }
-
-               if (f.instance)  {
-                       st.add_field (f.type_reference.get_cname (), f.get_cname ());
-                       if (f.type_reference.data_type is Array && !f.no_array_length) {
-                               // create fields to store array dimensions
-                               var arr = (Array) f.type_reference.data_type;
-                               
-                               for (int dim = 1; dim <= arr.rank; dim++) {
-                                       var len_type = new TypeReference ();
-                                       len_type.data_type = int_type.data_type;
-
-                                       st.add_field (len_type.get_cname (), get_array_length_cname (f.name, dim));
-                               }
-                       }
-
-                       if (f.initializer != null) {
-                               instance_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (lhs, (CCodeExpression) f.initializer.ccodenode)));
-                               
-                               if (f.type_reference.data_type is Array && !f.no_array_length &&
-                                   f.initializer is ArrayCreationExpression) {
-                                       var ma = new MemberAccess.simple (f.name);
-                                       ma.symbol_reference = f.symbol;
-                                       
-                                       var array_len_lhs = get_array_length_cexpression (ma, 1);
-                                       var sizes = ((ArrayCreationExpression) f.initializer).get_sizes ();
-                                       var size = (Expression) sizes.data;
-                                       instance_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (array_len_lhs, (CCodeExpression) size.ccodenode)));
-                               }
-                       }
-                       
-                       if (f.type_reference.takes_ownership && instance_dispose_fragment != null) {
-                               instance_dispose_fragment.append (new CCodeExpressionStatement (get_unref_expression (lhs, f.type_reference)));
-                       }
-               }
-       }
-
-       public override void visit_begin_method (Method! m) {
-               current_symbol = m.symbol;
-               current_return_type = m.return_type;
-       }
-       
-       private ref CCodeStatement create_method_type_check_statement (Method! m, DataType! t, bool non_null, string! var_name) {
-               return create_type_check_statement (m, m.return_type.data_type, t, non_null, var_name);
-       }
-       
-       private ref CCodeStatement create_property_type_check_statement (Property! prop, bool getter, DataType! t, bool non_null, string! var_name) {
-               if (getter) {
-                       return create_type_check_statement (prop, prop.type_reference.data_type, t, non_null, var_name);
-               } else {
-                       return create_type_check_statement (prop, null, t, non_null, var_name);
-               }
-       }
-       
-       private ref CCodeStatement create_type_check_statement (CodeNode! method_node, DataType ret_type, DataType! t, bool non_null, string! var_name) {
-               var ccheck = new CCodeFunctionCall ();
-               
-               if (t is Class || t is Interface) {
-                       var ctype_check = new CCodeFunctionCall (new CCodeIdentifier (t.get_upper_case_cname ("IS_")));
-                       ctype_check.add_argument (new CCodeIdentifier (var_name));
-                       
-                       ref CCodeExpression cexpr = ctype_check;
-                       if (!non_null) {
-                               var cnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier (var_name), new CCodeConstant ("NULL"));
-                       
-                               cexpr = new CCodeBinaryExpression (CCodeBinaryOperator.OR, cnull, ctype_check);
-                       }
-                       ccheck.add_argument (cexpr);
-               } else if (!non_null) {
-                       return null;
-               } else {
-                       var cnonnull = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier (var_name), new CCodeConstant ("NULL"));
-                       ccheck.add_argument (cnonnull);
-               }
-               
-               if (ret_type == null) {
-                       /* void function */
-                       ccheck.call = new CCodeIdentifier ("g_return_if_fail");
-               } else {
-                       ccheck.call = new CCodeIdentifier ("g_return_val_if_fail");
-                       
-                       if (ret_type.is_reference_type () || ret_type is Pointer) {
-                               ccheck.add_argument (new CCodeConstant ("NULL"));
-                       } else if (ret_type.get_default_value () != null) {
-                               ccheck.add_argument (new CCodeConstant (ret_type.get_default_value ()));
-                       } else {
-                               Report.warning (method_node.source_reference, "not supported return type for runtime type checks");
-                               return new CCodeExpressionStatement (new CCodeConstant ("0"));
-                       }
-               }
-               
-               return new CCodeExpressionStatement (ccheck);
-       }
-
-       private DataType find_parent_type (CodeNode node) {
-               var sym = node.symbol;
-               while (sym != null) {
-                       if (sym.node is DataType) {
-                               return (DataType) sym.node;
-                       }
-                       sym = sym.parent_symbol;
-               }
-               return null;
-       }
-       
-       private ref string! get_array_length_cname (string! array_cname, int dim) {
-               return "%s_length%d".printf (array_cname, dim);
-       }
-
-       public override void visit_end_method (Method! m) {
-               current_symbol = current_symbol.parent_symbol;
-               current_return_type = null;
-
-               if (current_type_symbol != null && current_type_symbol.node is Interface) {
-                       var iface = (Interface) current_type_symbol.node;
-                       if (iface.is_static) {
-                               return;
-                       }
-               }
-
-               if (current_symbol.parent_symbol != null &&
-                   current_symbol.parent_symbol.node is Method) {
-                       /* lambda expressions produce nested methods */
-                       var up_method = (Method) current_symbol.parent_symbol.node;
-                       current_return_type = up_method.return_type;
-               }
-
-               function = new CCodeFunction (m.get_real_cname (), m.return_type.get_cname ());
-               CCodeFunctionDeclarator vdeclarator = null;
-               
-               CCodeFormalParameter instance_param = null;
-               
-               if (m.instance) {
-                       var this_type = new TypeReference ();
-                       this_type.data_type = find_parent_type (m);
-                       if (m.base_interface_method != null) {
-                               var base_type = new TypeReference ();
-                               base_type.data_type = (DataType) m.base_interface_method.symbol.parent_symbol.node;
-                               instance_param = new CCodeFormalParameter ("base", base_type.get_cname ());
-                       } else if (m.overrides) {
-                               var base_type = new TypeReference ();
-                               base_type.data_type = (DataType) m.base_method.symbol.parent_symbol.node;
-                               instance_param = new CCodeFormalParameter ("base", base_type.get_cname ());
-                       } else {
-                               if (m.instance_by_reference) {
-                                       instance_param = new CCodeFormalParameter ("*self", this_type.get_cname ());
-                               } else {
-                                       instance_param = new CCodeFormalParameter ("self", this_type.get_cname ());
-                               }
-                       }
-                       if (!m.instance_last) {
-                               function.add_parameter (instance_param);
-                       }
-                       
-                       if (m.is_abstract || m.is_virtual) {
-                               var vdecl = new CCodeDeclaration (m.return_type.get_cname ());
-                               vdeclarator = new CCodeFunctionDeclarator (m.name);
-                               vdecl.add_declarator (vdeclarator);
-                               type_struct.add_declaration (vdecl);
-
-                               vdeclarator.add_parameter (instance_param);
-                       }
-               }
-
-               if (m is CreationMethod && current_class != null) {
-                       // memory management for generic types
-                       foreach (TypeParameter type_param in current_class.get_type_parameters ()) {
-                               var cparam = new CCodeFormalParameter ("%s_destroy_func".printf (type_param.name.down ()), "GDestroyNotify");
-                               function.add_parameter (cparam);
-                       }
-               }
-
-               var params = m.get_parameters ();
-               foreach (FormalParameter param in params) {
-                       if (!param.no_array_length && param.type_reference.data_type is Array) {
-                               var arr = (Array) param.type_reference.data_type;
-                               
-                               var length_ctype = "int";
-                               if (param.type_reference.is_out) {
-                                       length_ctype = "int*";
-                               }
-                               
-                               for (int dim = 1; dim <= arr.rank; dim++) {
-                                       var cparam = new CCodeFormalParameter (get_array_length_cname (param.name, dim), length_ctype);
-                                       function.add_parameter (cparam);
-                                       if (vdeclarator != null) {
-                                               vdeclarator.add_parameter (cparam);
-                                       }
-                               }
-                       }
-               
-                       function.add_parameter ((CCodeFormalParameter) param.ccodenode);
-                       if (vdeclarator != null) {
-                               vdeclarator.add_parameter ((CCodeFormalParameter) param.ccodenode);
-                       }
-               }
-               
-               if (m.instance && m.instance_last) {
-                       function.add_parameter (instance_param);
-               }
-
-               /* real function declaration and definition not needed
-                * for abstract methods */
-               if (!m.is_abstract) {
-                       if (m.access != MemberAccessibility.PRIVATE && m.base_method == null && m.base_interface_method == null) {
-                               /* public methods need function declaration in
-                                * header file except virtual/overridden methods */
-                               header_type_member_declaration.append (function.copy ());
-                       } else {
-                               /* declare all other functions in source file to
-                                * avoid dependency on order within source file */
-                               function.modifiers |= CCodeModifiers.STATIC;
-                               source_type_member_declaration.append (function.copy ());
-                       }
-                       
-                       /* Methods imported from a plain C file don't
-                        * have a body, e.g. Vala.Parser.parse_file () */
-                       if (m.body != null) {
-                               function.block = (CCodeBlock) m.body.ccodenode;
-
-                               var cinit = new CCodeFragment ();
-                               function.block.prepend_statement (cinit);
-
-                               if (m.symbol.parent_symbol.node is Class) {
-                                       var cl = (Class) m.symbol.parent_symbol.node;
-                                       if (m.overrides || m.base_interface_method != null) {
-                                               var ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null)));
-                                               ccall.add_argument (new CCodeIdentifier ("base"));
-                                               
-                                               var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
-                                               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
-                                               
-                                               cinit.append (cdecl);
-                                       } else if (m.instance) {
-                                               cinit.append (create_method_type_check_statement (m, cl, true, "self"));
-                                       }
-                               }
-                               foreach (FormalParameter param in m.get_parameters ()) {
-                                       var t = param.type_reference.data_type;
-                                       if (t != null && t.is_reference_type () && !param.type_reference.is_out) {
-                                               var type_check = create_method_type_check_statement (m, t, param.type_reference.non_null, param.name);
-                                               if (type_check != null) {
-                                                       cinit.append (type_check);
-                                               }
-                                       }
-                               }
-
-                               if (m.source_reference != null && m.source_reference.comment != null) {
-                                       source_type_member_definition.append (new CCodeComment (m.source_reference.comment));
-                               }
-                               source_type_member_definition.append (function);
-                               
-                               if (m is CreationMethod) {
-                                       if (current_class != null) {
-                                               int n_params = ((CreationMethod) m).n_construction_params;
-                                               n_params += (int) current_class.get_type_parameters ().length ();
-
-                                               // declare construction parameter array
-                                               var cparamsinit = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
-                                               cparamsinit.add_argument (new CCodeIdentifier ("GParameter"));
-                                               cparamsinit.add_argument (new CCodeConstant (n_params.to_string ()));
-                                               
-                                               var cdecl = new CCodeDeclaration ("GParameter *");
-                                               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params", cparamsinit));
-                                               cinit.append (cdecl);
-                                               
-                                               cdecl = new CCodeDeclaration ("GParameter *");
-                                               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params_it", new CCodeIdentifier ("__params")));
-                                               cinit.append (cdecl);
-
-                                               /* destroy func properties for generic types */
-                                               foreach (TypeParameter type_param in current_class.get_type_parameters ()) {
-                                                       string func_name = "%s_destroy_func".printf (type_param.name.down ());
-                                                       var func_name_constant = new CCodeConstant ("\"%s-destroy-func\"".printf (type_param.name.down ()));
-
-                                                       // this property is used as a construction parameter
-                                                       var cpointer = new CCodeIdentifier ("__params_it");
-
-                                                       var ccomma = new CCodeCommaExpression ();
-                                                       // set name in array for current parameter
-                                                       var cnamemember = new CCodeMemberAccess.pointer (cpointer, "name");
-                                                       ccomma.append_expression (new CCodeAssignment (cnamemember, func_name_constant));
-                                                       var gvaluearg = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeMemberAccess.pointer (cpointer, "value"));
-
-                                                       // initialize GValue in array for current parameter
-                                                       var cvalueinit = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
-                                                       cvalueinit.add_argument (gvaluearg);
-                                                       cvalueinit.add_argument (new CCodeIdentifier ("G_TYPE_POINTER"));
-                                                       ccomma.append_expression (cvalueinit);
-
-                                                       // set GValue for current parameter
-                                                       var cvalueset = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_pointer"));
-                                                       cvalueset.add_argument (gvaluearg);
-                                                       cvalueset.add_argument (new CCodeIdentifier (func_name));
-                                                       ccomma.append_expression (cvalueset);
-
-                                                       // move pointer to next parameter in array
-                                                       ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, cpointer));
-
-                                                       cinit.append (new CCodeExpressionStatement (ccomma));
-                                               }
-                                       } else {
-                                               var st = (Struct) m.symbol.parent_symbol.node;
-                                               var cdecl = new CCodeDeclaration (st.get_cname () + "*");
-                                               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
-                                               ccall.add_argument (new CCodeConstant (st.get_cname ()));
-                                               ccall.add_argument (new CCodeConstant ("1"));
-                                               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
-                                               cinit.append (cdecl);
-                                       }
-                               }
-
-                               if (context.module_init_method == m && in_plugin) {
-                                       // GTypeModule-based plug-in, register types
-                                       cinit.append (module_init_fragment);
+                                       }
+                                       cdecl.add_declarator (var_decl);
+                                       cdecl.modifiers = CCodeModifiers.STATIC;
+                                       source_type_member_declaration.append (cdecl);
                                }
                        }
                }
-               
-               if (m.is_abstract || m.is_virtual) {
-                       var vfunc = new CCodeFunction (m.get_cname (), m.return_type.get_cname ());
-
-                       var this_type = new TypeReference ();
-                       this_type.data_type = (DataType) m.symbol.parent_symbol.node;
-
-                       var cparam = new CCodeFormalParameter ("self", this_type.get_cname ());
-                       vfunc.add_parameter (cparam);
-                       
-                       var vblock = new CCodeBlock ();
-                       
-                       CCodeFunctionCall vcast = null;
-                       if (m.symbol.parent_symbol.node is Interface) {
-                               var iface = (Interface) m.symbol.parent_symbol.node;
 
-                               vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_INTERFACE".printf (iface.get_upper_case_cname (null))));
-                       } else {
-                               var cl = (Class) m.symbol.parent_symbol.node;
+               if (f.instance)  {
+                       st.add_field (f.type_reference.get_cname (), f.get_cname ());
+                       if (f.type_reference.data_type is Array && !f.no_array_length) {
+                               // create fields to store array dimensions
+                               var arr = (Array) f.type_reference.data_type;
+                               
+                               for (int dim = 1; dim <= arr.rank; dim++) {
+                                       var len_type = new TypeReference ();
+                                       len_type.data_type = int_type.data_type;
 
-                               vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS".printf (cl.get_upper_case_cname (null))));
-                       }
-                       vcast.add_argument (new CCodeIdentifier ("self"));
-               
-                       var vcall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, m.name));
-                       vcall.add_argument (new CCodeIdentifier ("self"));
-               
-                       var params = m.get_parameters ();
-                       foreach (FormalParameter param in params) {
-                               vfunc.add_parameter ((CCodeFormalParameter) param.ccodenode);
-                               vcall.add_argument (new CCodeIdentifier (param.name));
+                                       st.add_field (len_type.get_cname (), get_array_length_cname (f.name, dim));
+                               }
                        }
 
-                       if (m.return_type.data_type == null) {
-                               vblock.add_statement (new CCodeExpressionStatement (vcall));
-                       } else {
-                               /* pass method return value */
-                               vblock.add_statement (new CCodeReturnStatement (vcall));
+                       if (f.initializer != null) {
+                               instance_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (lhs, (CCodeExpression) f.initializer.ccodenode)));
+                               
+                               if (f.type_reference.data_type is Array && !f.no_array_length &&
+                                   f.initializer is ArrayCreationExpression) {
+                                       var ma = new MemberAccess.simple (f.name);
+                                       ma.symbol_reference = f.symbol;
+                                       
+                                       var array_len_lhs = get_array_length_cexpression (ma, 1);
+                                       var sizes = ((ArrayCreationExpression) f.initializer).get_sizes ();
+                                       var size = (Expression) sizes.data;
+                                       instance_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (array_len_lhs, (CCodeExpression) size.ccodenode)));
+                               }
                        }
-
-                       header_type_member_declaration.append (vfunc.copy ());
                        
-                       vfunc.block = vblock;
-                       
-                       source_type_member_definition.append (vfunc);
-               }
-               
-               if (m is CreationMethod) {
-                       var creturn = new CCodeReturnStatement ();
-                       creturn.return_expression = new CCodeIdentifier ("self");
-                       function.block.add_statement (creturn);
-               }
-               
-               bool return_value = true;
-               bool args_parameter = true;
-               if (is_possible_entry_point (m, ref return_value, ref args_parameter)) {
-                       // m is possible entry point, add appropriate startup code
-                       var cmain = new CCodeFunction ("main", "int");
-                       cmain.add_parameter (new CCodeFormalParameter ("argc", "int"));
-                       cmain.add_parameter (new CCodeFormalParameter ("argv", "char **"));
-                       var main_block = new CCodeBlock ();
-                       main_block.add_statement (new CCodeExpressionStatement (new CCodeFunctionCall (new CCodeIdentifier ("g_type_init"))));
-                       var main_call = new CCodeFunctionCall (new CCodeIdentifier (function.name));
-                       if (args_parameter) {
-                               main_call.add_argument (new CCodeIdentifier ("argc"));
-                               main_call.add_argument (new CCodeIdentifier ("argv"));
-                       }
-                       if (return_value) {
-                               main_block.add_statement (new CCodeReturnStatement (main_call));
-                       } else {
-                               // method returns void, always use 0 as exit code
-                               main_block.add_statement (new CCodeExpressionStatement (main_call));
-                               main_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("0")));
+                       if (f.type_reference.takes_ownership && instance_dispose_fragment != null) {
+                               instance_dispose_fragment.append (new CCodeExpressionStatement (get_unref_expression (lhs, f.type_reference)));
                        }
-                       cmain.block = main_block;
-                       source_type_member_definition.append (cmain);
-               }
-       }
-       
-       public override void visit_begin_creation_method (CreationMethod! m) {
-               current_symbol = m.symbol;
-               current_return_type = m.return_type;
-               in_creation_method = true;
-       }
-       
-       public override void visit_end_creation_method (CreationMethod! m) {
-               if (current_class != null && m.body != null) {
-                       add_object_creation ((CCodeBlock) m.body.ccodenode);
                }
-
-               in_creation_method = false;
-
-               visit_end_method (m);
        }
-       
-       private bool is_possible_entry_point (Method! m, ref bool return_value, ref bool args_parameter) {
-               if (m.name == null || m.name != "main") {
-                       // method must be called "main"
-                       return false;
-               }
-               
-               if (m.instance) {
-                       // method must be static
-                       return false;
-               }
-               
-               if (m.return_type.data_type == null) {
-                       return_value = false;
-               } else if (m.return_type.data_type == int_type.data_type) {
-                       return_value = true;
-               } else {
-                       // return type must be void or int
-                       return false;
-               }
-               
-               var params = m.get_parameters ();
-               if (params.length () == 0) {
-                       // method may have no parameters
-                       args_parameter = false;
-                       return true;
-               }
-               
-               if (params.length () > 1) {
-                       // method must not have more than one parameter
-                       return false;
-               }
-               
-               var param = (FormalParameter) params.data;
 
-               if (param.type_reference.is_out) {
-                       // parameter must not be an out parameter
-                       return false;
-               }
-               
-               if (!(param.type_reference.data_type is Array)) {
-                       // parameter must be an array
-                       return false;
-               }
-               
-               var array_type = (Array) param.type_reference.data_type;
-               if (array_type.element_type != string_type.data_type) {
-                       // parameter must be an array of strings
-                       return false;
-               }
-               
-               args_parameter = true;
-               return true;
-       }
-       
        public override void visit_formal_parameter (FormalParameter! p) {
                if (!p.ellipsis) {
                        p.ccodenode = new CCodeFormalParameter (p.name, p.type_reference.get_cname (false, !p.type_reference.takes_ownership));
@@ -1781,217 +493,7 @@ public class Vala.CodeGenerator : CodeVisitor {
                        source_type_member_definition.append (function);
                }
        }
-       
-       private string get_marshaller_type_name (TypeReference t) {
-               if (t.type_parameter != null) {
-                       return ("POINTER");
-               } else if (t.data_type == null) {
-                       return ("VOID");
-               } else {
-                       return t.data_type.get_marshaller_type_name ();
-               }
-       }
-       
-       private ref string get_signal_marshaller_function (Signal! sig, string prefix = null) {
-               var signature = get_signal_signature (sig);
-               string ret;
-               var params = sig.get_parameters ();
-               
-               if (prefix == null) {
-                       // FIXME remove equality check with cast in next revision
-                       if (predefined_marshal_list.lookup (signature) != (bool) null) {
-                               prefix = "g_cclosure_marshal";
-                       } else {
-                               prefix = "g_cclosure_user_marshal";
-                       }
-               }
-               
-               ret = "%s_%s_".printf (prefix, get_marshaller_type_name (sig.return_type));
-               
-               if (params == null) {
-                       ret = ret + "_VOID";
-               } else {
-                       foreach (FormalParameter p in params) {
-                               ret = "%s_%s".printf (ret, get_marshaller_type_name (p.type_reference));
-                       }
-               }
-               
-               return ret;
-       }
-       
-       private string get_value_type_name_from_type_reference (TypeReference! t) {
-               if (t.type_parameter != null) {
-                       return "gpointer";
-               } else if (t.data_type == null) {
-                       return "void";
-               } else if (t.data_type is Class || t.data_type is Interface) {
-                       return "GObject *";
-               } else if (t.data_type is Struct) {
-                       if (((Struct) t.data_type).is_reference_type ()) {
-                               return "gpointer";
-                       } else {
-                               return t.data_type.get_cname ();
-                       }
-               } else if (t.data_type is Enum) {
-                       return "gint";
-               } else if (t.data_type is Flags) {
-                       return "guint";
-               } else if (t.data_type is Array) {
-                       return "gpointer";
-               }
-               
-               return null;
-       }
-       
-       private ref string get_signal_signature (Signal! sig) {
-               string signature;
-               var params = sig.get_parameters ();
-               
-               signature = "%s:".printf (get_marshaller_type_name (sig.return_type));
-               if (params == null) {
-                       signature = signature + "VOID";
-               } else {
-                       bool first = true;
-                       foreach (FormalParameter p in params) {
-                               if (first) {
-                                       signature = signature + get_marshaller_type_name (p.type_reference);
-                                       first = false;
-                               } else {
-                                       signature = "%s,%s".printf (signature, get_marshaller_type_name (p.type_reference));
-                               }
-                       }
-               }
-               
-               return signature;
-       }
-       
-       public override void visit_end_signal (Signal! sig) {
-               string signature;
-               var params = sig.get_parameters ();
-               int n_params, i;
-               
-               /* check whether a signal with the same signature already exists for this source file (or predefined) */
-               signature = get_signal_signature (sig);
-               // FIXME remove equality checks with cast in next revision
-               if (predefined_marshal_list.lookup (signature) != (bool) null || user_marshal_list.lookup (signature) != (bool) null) {
-                       return;
-               }
-               
-               var signal_marshaller = new CCodeFunction (get_signal_marshaller_function (sig), "void");
-               signal_marshaller.modifiers = CCodeModifiers.STATIC;
-               
-               signal_marshaller.add_parameter (new CCodeFormalParameter ("closure", "GClosure *"));
-               signal_marshaller.add_parameter (new CCodeFormalParameter ("return_value", "GValue *"));
-               signal_marshaller.add_parameter (new CCodeFormalParameter ("n_param_values", "guint"));
-               signal_marshaller.add_parameter (new CCodeFormalParameter ("param_values", "const GValue *"));
-               signal_marshaller.add_parameter (new CCodeFormalParameter ("invocation_hint", "gpointer"));
-               signal_marshaller.add_parameter (new CCodeFormalParameter ("marshal_data", "gpointer"));
-               
-               source_signal_marshaller_declaration.append (signal_marshaller.copy ());
-               
-               var marshaller_body = new CCodeBlock ();
-               
-               var callback_decl = new CCodeFunctionDeclarator (get_signal_marshaller_function (sig, "GMarshalFunc"));
-               callback_decl.add_parameter (new CCodeFormalParameter ("data1", "gpointer"));
-               n_params = 1;
-               foreach (FormalParameter p in params) {
-                       callback_decl.add_parameter (new CCodeFormalParameter ("arg_%d".printf (n_params), get_value_type_name_from_type_reference (p.type_reference)));
-                       n_params++;
-               }
-               callback_decl.add_parameter (new CCodeFormalParameter ("data2", "gpointer"));
-               marshaller_body.add_statement (new CCodeTypeDefinition (get_value_type_name_from_type_reference (sig.return_type), callback_decl));
-               
-               var var_decl = new CCodeDeclaration (get_signal_marshaller_function (sig, "GMarshalFunc"));
-               var_decl.modifiers = CCodeModifiers.REGISTER;
-               var_decl.add_declarator (new CCodeVariableDeclarator ("callback"));
-               marshaller_body.add_statement (var_decl);
-               
-               var_decl = new CCodeDeclaration ("GCClosure *");
-               var_decl.modifiers = CCodeModifiers.REGISTER;
-               var_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("cc", new CCodeCastExpression (new CCodeIdentifier ("closure"), "GCClosure *")));
-               marshaller_body.add_statement (var_decl);
-               
-               var_decl = new CCodeDeclaration ("gpointer");
-               var_decl.modifiers = CCodeModifiers.REGISTER;
-               var_decl.add_declarator (new CCodeVariableDeclarator ("data1"));
-               var_decl.add_declarator (new CCodeVariableDeclarator ("data2"));
-               marshaller_body.add_statement (var_decl);
-               
-               CCodeFunctionCall fc;
-               
-               if (sig.return_type.data_type != null) {
-                       var_decl = new CCodeDeclaration (get_value_type_name_from_type_reference (sig.return_type));
-                       var_decl.add_declarator (new CCodeVariableDeclarator ("v_return"));
-                       marshaller_body.add_statement (var_decl);
-                       
-                       fc = new CCodeFunctionCall (new CCodeIdentifier ("g_return_if_fail"));
-                       fc.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("return_value"), new CCodeConstant ("NULL")));
-                       marshaller_body.add_statement (new CCodeExpressionStatement (fc));
-               }
-               
-               fc = new CCodeFunctionCall (new CCodeIdentifier ("g_return_if_fail"));
-               fc.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier ("n_param_values"), new CCodeConstant (n_params.to_string())));
-               marshaller_body.add_statement (new CCodeExpressionStatement (fc));
-               
-               var data = new CCodeMemberAccess (new CCodeIdentifier ("closure"), "data", true);
-               var param = new CCodeMemberAccess (new CCodeMemberAccess (new CCodeIdentifier ("param_values"), "data[0]", true), "v_pointer");
-               var cond = new CCodeFunctionCall (new CCodeConstant ("G_CCLOSURE_SWAP_DATA"));
-               cond.add_argument (new CCodeIdentifier ("closure"));
-               var true_block = new CCodeBlock ();
-               true_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data1"), data)));
-               true_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data2"), param)));
-               var false_block = new CCodeBlock ();
-               false_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data1"), param)));
-               false_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data2"), data)));
-               marshaller_body.add_statement (new CCodeIfStatement (cond, true_block, false_block));
-               
-               var c_assign = new CCodeAssignment (new CCodeIdentifier ("callback"), new CCodeCastExpression (new CCodeConditionalExpression (new CCodeIdentifier ("marshal_data"), new CCodeIdentifier ("marshal_data"), new CCodeMemberAccess (new CCodeIdentifier ("cc"), "callback", true)), get_signal_marshaller_function (sig, "GMarshalFunc")));
-               marshaller_body.add_statement (new CCodeExpressionStatement (c_assign));
-               
-               fc = new CCodeFunctionCall (new CCodeIdentifier ("callback"));
-               fc.add_argument (new CCodeIdentifier ("data1"));
-               i = 1;
-               foreach (FormalParameter p in params) {
-                       string get_value_function;
-                       if (p.type_reference.type_parameter != null) {
-                               get_value_function = "g_value_get_pointer";
-                       } else {
-                               get_value_function = p.type_reference.data_type.get_get_value_function ();
-                       }
-                       var inner_fc = new CCodeFunctionCall (new CCodeIdentifier (get_value_function));
-                       inner_fc.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("param_values"), new CCodeIdentifier (i.to_string ())));
-                       fc.add_argument (inner_fc);
-                       i++;
-               }
-               fc.add_argument (new CCodeIdentifier ("data2"));
-               
-               if (sig.return_type.data_type != null) {
-                       marshaller_body.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("v_return"), fc)));
-                       
-                       CCodeFunctionCall set_fc;
-                       if (sig.return_type.type_parameter != null) {
-                               set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_pointer"));
-                       } else if (sig.return_type.data_type is Class || sig.return_type.data_type is Interface) {
-                               set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_object"));
-                       } else if (sig.return_type.data_type == string_type.data_type) {
-                               set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_string"));
-                       } else {
-                               set_fc = new CCodeFunctionCall (new CCodeIdentifier (sig.return_type.data_type.get_set_value_function ()));
-                       }
-                       set_fc.add_argument (new CCodeIdentifier ("return_value"));
-                       set_fc.add_argument (new CCodeIdentifier ("v_return"));
-                       
-                       marshaller_body.add_statement (new CCodeExpressionStatement (set_fc));
-               } else {
-                       marshaller_body.add_statement (new CCodeExpressionStatement (fc));
-               }
-               
-               signal_marshaller.block = marshaller_body;
-               
-               source_signal_marshaller_definition.append (signal_marshaller);
-               user_marshal_list.insert (signature, true);
-       }
-       
+
        public override void visit_end_constructor (Constructor! c) {
                var cl = (Class) c.symbol.parent_symbol.node;
        
@@ -2886,270 +1388,76 @@ public class Vala.CodeGenerator : CodeVisitor {
                        Report.error (expr.source_reference, "Creating arrays with rank greater than 1 is not supported yet");
                }
                
-               var sizes = expr.get_sizes ();
-               var gnew = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
-               gnew.add_argument (new CCodeIdentifier (expr.element_type.get_cname ()));
-               /* FIXME: had to add Expression cast due to possible compiler bug */
-               gnew.add_argument ((CCodeExpression) ((Expression) sizes.first ().data).ccodenode);
-               
-               if (expr.initializer_list != null) {
-                       var ce = new CCodeCommaExpression ();
-                       var temp_var = get_temp_variable_declarator (expr.static_type);
-                       var name_cnode = new CCodeIdentifier (temp_var.name);
-                       int i = 0;
-                       
-                       temp_vars.prepend (temp_var);
-                       
-                       /* FIXME: had to add Expression cast due to possible compiler bug */
-                       ce.append_expression (new CCodeAssignment (name_cnode, gnew));
-                       
-                       foreach (Expression e in expr.initializer_list.get_initializers ()) {
-                               ce.append_expression (new CCodeAssignment (new CCodeElementAccess (name_cnode, new CCodeConstant (i.to_string ())), (CCodeExpression) e.ccodenode));
-                               i++;
-                       }
-                       
-                       ce.append_expression (name_cnode);
-                       
-                       expr.ccodenode = ce;
-               } else {
-                       expr.ccodenode = gnew;
-               }
-       }
-
-       public override void visit_boolean_literal (BooleanLiteral! expr) {
-               expr.ccodenode = new CCodeConstant (expr.value ? "TRUE" : "FALSE");
-       }
-
-       public override void visit_character_literal (CharacterLiteral! expr) {
-               if (expr.get_char () >= 0x20 && expr.get_char () < 0x80) {
-                       expr.ccodenode = new CCodeConstant (expr.value);
-               } else {
-                       expr.ccodenode = new CCodeConstant ("%uU".printf (expr.get_char ()));
-               }
-       }
-
-       public override void visit_integer_literal (IntegerLiteral! expr) {
-               expr.ccodenode = new CCodeConstant (expr.value);
-       }
-
-       public override void visit_real_literal (RealLiteral! expr) {
-               expr.ccodenode = new CCodeConstant (expr.value);
-       }
-
-       public override void visit_string_literal (StringLiteral! expr) {
-               expr.ccodenode = new CCodeConstant (expr.value);
-       }
-
-       public override void visit_null_literal (NullLiteral! expr) {
-               expr.ccodenode = new CCodeConstant ("NULL");
-       }
-
-       public override void visit_literal_expression (LiteralExpression! expr) {
-               expr.ccodenode = expr.literal.ccodenode;
-               
-               visit_expression (expr);
-       }
-       
-       private void process_cmember (MemberAccess! expr, CCodeExpression pub_inst, DataType base_type) {
-               if (expr.symbol_reference.node is Method) {
-                       var m = (Method) expr.symbol_reference.node;
-                       
-                       if (expr.inner is BaseAccess) {
-                               if (m.base_interface_method != null) {
-                                       var base_iface = (Interface) m.base_interface_method.symbol.parent_symbol.node;
-                                       string parent_iface_var = "%s_%s_parent_iface".printf (current_class.get_lower_case_cname (null), base_iface.get_lower_case_cname (null));
-
-                                       expr.ccodenode = new CCodeMemberAccess.pointer (new CCodeIdentifier (parent_iface_var), m.name);
-                                       return;
-                               } else if (m.base_method != null) {
-                                       var base_class = (Class) m.base_method.symbol.parent_symbol.node;
-                                       var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (base_class.get_upper_case_cname (null))));
-                                       vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (current_class.get_lower_case_cname (null))));
-                                       
-                                       expr.ccodenode = new CCodeMemberAccess.pointer (vcast, m.name);
-                                       return;
-                               }
-                       }
-                       
-                       if (m.base_interface_method != null) {
-                               expr.ccodenode = new CCodeIdentifier (m.base_interface_method.get_cname ());
-                       } else if (m.base_method != null) {
-                               expr.ccodenode = new CCodeIdentifier (m.base_method.get_cname ());
-                       } else {
-                               expr.ccodenode = new CCodeIdentifier (m.get_cname ());
-                       }
-               } else if (expr.symbol_reference.node is ArrayLengthField) {
-                       expr.ccodenode = get_array_length_cexpression (expr.inner, 1);
-               } else if (expr.symbol_reference.node is Field) {
-                       var f = (Field) expr.symbol_reference.node;
-                       if (f.instance) {
-                               ref CCodeExpression typed_inst;
-                               if (f.symbol.parent_symbol.node != base_type) {
-                                       // FIXME: use C cast if debugging disabled
-                                       typed_inst = new CCodeFunctionCall (new CCodeIdentifier (((DataType) f.symbol.parent_symbol.node).get_upper_case_cname (null)));
-                                       ((CCodeFunctionCall) typed_inst).add_argument (pub_inst);
-                               } else {
-                                       typed_inst = pub_inst;
-                               }
-                               ref CCodeExpression inst;
-                               if (f.access == MemberAccessibility.PRIVATE) {
-                                       inst = new CCodeMemberAccess.pointer (typed_inst, "priv");
-                               } else {
-                                       inst = typed_inst;
-                               }
-                               if (((DataType) f.symbol.parent_symbol.node).is_reference_type ()) {
-                                       expr.ccodenode = new CCodeMemberAccess.pointer (inst, f.get_cname ());
-                               } else {
-                                       expr.ccodenode = new CCodeMemberAccess (inst, f.get_cname ());
-                               }
-                       } else {
-                               expr.ccodenode = new CCodeIdentifier (f.get_cname ());
-                       }
-               } else if (expr.symbol_reference.node is Constant) {
-                       var c = (Constant) expr.symbol_reference.node;
-                       expr.ccodenode = new CCodeIdentifier (c.get_cname ());
-               } else if (expr.symbol_reference.node is Property) {
-                       var prop = (Property) expr.symbol_reference.node;
-
-                       if (!prop.no_accessor_method) {
-                               var base_property = prop;
-                               if (prop.base_property != null) {
-                                       base_property = prop.base_property;
-                               } else if (prop.base_interface_property != null) {
-                                       base_property = prop.base_interface_property;
-                               }
-                               var base_property_type = (DataType) base_property.symbol.parent_symbol.node;
-                               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_get_%s".printf (base_property_type.get_lower_case_cname (null), base_property.name)));
-                               
-                               /* explicitly use strong reference as ccast
-                                * gets unrefed at the end of the inner block
-                                */
-                               ref CCodeExpression typed_pub_inst = pub_inst;
-
-                               /* cast if necessary */
-                               if (base_property_type != base_type) {
-                                       // FIXME: use C cast if debugging disabled
-                                       var ccast = new CCodeFunctionCall (new CCodeIdentifier (base_property_type.get_upper_case_cname (null)));
-                                       ccast.add_argument (pub_inst);
-                                       typed_pub_inst = ccast;
-                               }
-
-                               ccall.add_argument (typed_pub_inst);
-                               expr.ccodenode = ccall;
-                       } else {
-                               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get"));
-                       
-                               var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
-                               ccast.add_argument (pub_inst);
-                               ccall.add_argument (ccast);
-                               
-                               // property name is second argument of g_object_get
-                               ccall.add_argument (prop.get_canonical_cconstant ());
-                               
-                               
-                               // we need a temporary variable to save the property value
-                               var temp_decl = get_temp_variable_declarator (expr.static_type);
-                               temp_vars.prepend (temp_decl);
-
-                               var ctemp = new CCodeIdentifier (temp_decl.name);
-                               ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
-                               
-                               
-                               ccall.add_argument (new CCodeConstant ("NULL"));
-                               
-                               var ccomma = new CCodeCommaExpression ();
-                               ccomma.append_expression (ccall);
-                               ccomma.append_expression (ctemp);
-                               expr.ccodenode = ccomma;
-                       }
-               } else if (expr.symbol_reference.node is EnumValue) {
-                       var ev = (EnumValue) expr.symbol_reference.node;
-                       expr.ccodenode = new CCodeConstant (ev.get_cname ());
-               } else if (expr.symbol_reference.node is VariableDeclarator) {
-                       var decl = (VariableDeclarator) expr.symbol_reference.node;
-                       expr.ccodenode = new CCodeIdentifier (decl.name);
-               } else if (expr.symbol_reference.node is FormalParameter) {
-                       var p = (FormalParameter) expr.symbol_reference.node;
-                       if (p.name == "this") {
-                               expr.ccodenode = pub_inst;
-                       } else {
-                               if (p.type_reference.is_out || p.type_reference.reference_to_value_type) {
-                                       expr.ccodenode = new CCodeIdentifier ("(*%s)".printf (p.name));
-                               } else {
-                                       expr.ccodenode = new CCodeIdentifier (p.name);
-                               }
+               var sizes = expr.get_sizes ();
+               var gnew = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
+               gnew.add_argument (new CCodeIdentifier (expr.element_type.get_cname ()));
+               /* FIXME: had to add Expression cast due to possible compiler bug */
+               gnew.add_argument ((CCodeExpression) ((Expression) sizes.first ().data).ccodenode);
+               
+               if (expr.initializer_list != null) {
+                       var ce = new CCodeCommaExpression ();
+                       var temp_var = get_temp_variable_declarator (expr.static_type);
+                       var name_cnode = new CCodeIdentifier (temp_var.name);
+                       int i = 0;
+                       
+                       temp_vars.prepend (temp_var);
+                       
+                       /* FIXME: had to add Expression cast due to possible compiler bug */
+                       ce.append_expression (new CCodeAssignment (name_cnode, gnew));
+                       
+                       foreach (Expression e in expr.initializer_list.get_initializers ()) {
+                               ce.append_expression (new CCodeAssignment (new CCodeElementAccess (name_cnode, new CCodeConstant (i.to_string ())), (CCodeExpression) e.ccodenode));
+                               i++;
                        }
-               } else if (expr.symbol_reference.node is Signal) {
-                       var sig = (Signal) expr.symbol_reference.node;
-                       var cl = (DataType) sig.symbol.parent_symbol.node;
                        
-                       if (sig.has_emitter) {
-                               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_%s".printf (cl.get_lower_case_cname (null), sig.name)));
-                               
-                               /* explicitly use strong reference as ccast
-                                * gets unrefed at the end of the inner block
-                                */
-                               ref CCodeExpression typed_pub_inst = pub_inst;
-
-                               /* cast if necessary */
-                               if (cl != base_type) {
-                                       // FIXME: use C cast if debugging disabled
-                                       var ccast = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null)));
-                                       ccast.add_argument (pub_inst);
-                                       typed_pub_inst = ccast;
-                               }
-
-                               ccall.add_argument (typed_pub_inst);
-                               expr.ccodenode = ccall;
-                       } else {
-                               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
+                       ce.append_expression (name_cnode);
+                       
+                       expr.ccodenode = ce;
+               } else {
+                       expr.ccodenode = gnew;
+               }
+       }
 
-                               // FIXME: use C cast if debugging disabled
-                               var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
-                               ccast.add_argument (pub_inst);
-                               ccall.add_argument (ccast);
+       public override void visit_boolean_literal (BooleanLiteral! expr) {
+               expr.ccodenode = new CCodeConstant (expr.value ? "TRUE" : "FALSE");
+       }
 
-                               ccall.add_argument (sig.get_canonical_cconstant ());
-                               
-                               expr.ccodenode = ccall;
-                       }
+       public override void visit_character_literal (CharacterLiteral! expr) {
+               if (expr.get_char () >= 0x20 && expr.get_char () < 0x80) {
+                       expr.ccodenode = new CCodeConstant (expr.value);
+               } else {
+                       expr.ccodenode = new CCodeConstant ("%uU".printf (expr.get_char ()));
                }
        }
-       
-       public override void visit_parenthesized_expression (ParenthesizedExpression! expr) {
-               expr.ccodenode = new CCodeParenthesizedExpression ((CCodeExpression) expr.inner.ccodenode);
 
-               visit_expression (expr);
+       public override void visit_integer_literal (IntegerLiteral! expr) {
+               expr.ccodenode = new CCodeConstant (expr.value);
        }
 
-       public override void visit_member_access (MemberAccess! expr) {
-               CCodeExpression pub_inst = null;
-               DataType base_type = null;
-       
-               if (expr.inner == null) {
-                       pub_inst = new CCodeIdentifier ("self");
+       public override void visit_real_literal (RealLiteral! expr) {
+               expr.ccodenode = new CCodeConstant (expr.value);
+       }
 
-                       if (current_type_symbol != null) {
-                               /* base type is available if this is a type method */
-                               base_type = (DataType) current_type_symbol.node;
-                               
-                               if (!base_type.is_reference_type ()) {
-                                       pub_inst = new CCodeIdentifier ("(*self)");
-                               }
-                       }
-               } else {
-                       pub_inst = (CCodeExpression) expr.inner.ccodenode;
+       public override void visit_string_literal (StringLiteral! expr) {
+               expr.ccodenode = new CCodeConstant (expr.value);
+       }
 
-                       if (expr.inner.static_type != null) {
-                               base_type = expr.inner.static_type.data_type;
-                       }
-               }
+       public override void visit_null_literal (NullLiteral! expr) {
+               expr.ccodenode = new CCodeConstant ("NULL");
+       }
+
+       public override void visit_literal_expression (LiteralExpression! expr) {
+               expr.ccodenode = expr.literal.ccodenode;
+               
+               visit_expression (expr);
+       }
 
-               process_cmember (expr, pub_inst, base_type);
+       public override void visit_parenthesized_expression (ParenthesizedExpression! expr) {
+               expr.ccodenode = new CCodeParenthesizedExpression ((CCodeExpression) expr.inner.ccodenode);
 
                visit_expression (expr);
        }
-       
+
        private ref CCodeExpression! get_array_length_cexpression (Expression! array_expr, int dim) {
                bool is_out = false;
        
@@ -3261,225 +1569,6 @@ public class Vala.CodeGenerator : CodeVisitor {
                }
        }
 
-       public override void visit_end_invocation_expression (InvocationExpression! expr) {
-               var ccall = new CCodeFunctionCall ((CCodeExpression) expr.call.ccodenode);
-               
-               Method m = null;
-               List<weak FormalParameter> params;
-               
-               if (!(expr.call is MemberAccess)) {
-                       expr.error = true;
-                       Report.error (expr.source_reference, "unsupported method invocation");
-                       return;
-               }
-               
-               var ma = (MemberAccess) expr.call;
-               
-               if (expr.call.symbol_reference.node is Invokable) {
-                       var i = (Invokable) expr.call.symbol_reference.node;
-                       params = i.get_parameters ();
-                       
-                       if (i is Method) {
-                               m = (Method) i;
-                       } else if (i is Signal) {
-                               ccall = (CCodeFunctionCall) expr.call.ccodenode;
-                       }
-               }
-               
-               if (m is ArrayResizeMethod) {
-                       var array = (Array) m.symbol.parent_symbol.node;
-                       ccall.add_argument (new CCodeIdentifier (array.get_cname ()));
-               }
-               
-               /* explicitly use strong reference as ccall gets unrefed
-                * at end of inner block
-                */
-               ref CCodeExpression instance;
-               if (m != null && m.instance) {
-                       var base_method = m;
-                       if (m.base_interface_method != null) {
-                               base_method = m.base_interface_method;
-                       } else if (m.base_method != null) {
-                               base_method = m.base_method;
-                       }
-
-                       var req_cast = false;
-                       if (ma.inner == null) {
-                               instance = new CCodeIdentifier ("self");
-                               /* require casts for overriden and inherited methods */
-                               req_cast = m.overrides || m.base_interface_method != null || (m.symbol.parent_symbol != current_type_symbol);
-                       } else {
-                               instance = (CCodeExpression) ma.inner.ccodenode;
-                               /* reqiure casts if the type of the used instance is
-                                * different than the type which declared the method */
-                               req_cast = base_method.symbol.parent_symbol.node != ma.inner.static_type.data_type;
-                       }
-                       
-                       if (m.instance_by_reference && (ma.inner != null || m.symbol.parent_symbol != current_type_symbol)) {
-                               instance = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance);
-                       }
-                       
-                       if (req_cast && ((DataType) m.symbol.parent_symbol.node).is_reference_type ()) {
-                               // FIXME: use C cast if debugging disabled
-                               var ccall = new CCodeFunctionCall (new CCodeIdentifier (((DataType) base_method.symbol.parent_symbol.node).get_upper_case_cname (null)));
-                               ccall.add_argument (instance);
-                               instance = ccall;
-                       }
-                       
-                       if (!m.instance_last) {
-                               ccall.add_argument (instance);
-                       }
-               }
-               
-               bool ellipsis = false;
-               
-               var i = 1;
-               weak List<weak FormalParameter> params_it = params;
-               foreach (Expression arg in expr.get_argument_list ()) {
-                       /* explicitly use strong reference as ccall gets
-                        * unrefed at end of inner block
-                        */
-                       ref CCodeExpression cexpr = (CCodeExpression) arg.ccodenode;
-                       if (params_it != null) {
-                               var param = (FormalParameter) params_it.data;
-                               ellipsis = param.ellipsis;
-                               if (!ellipsis) {
-                                       if (param.type_reference.data_type != null
-                                           && param.type_reference.data_type.is_reference_type ()
-                                           && arg.static_type.data_type != null) {
-                                               if (!param.no_array_length && param.type_reference.data_type is Array) {
-                                                       var arr = (Array) param.type_reference.data_type;
-                                                       for (int dim = 1; dim <= arr.rank; dim++) {
-                                                               ccall.add_argument (get_array_length_cexpression (arg, dim));
-                                                       }
-                                               }
-                                               if (param.type_reference.data_type != arg.static_type.data_type) {
-                                                       // FIXME: use C cast if debugging disabled
-                                                       var ccall = new CCodeFunctionCall (new CCodeIdentifier (param.type_reference.data_type.get_upper_case_cname (null)));
-                                                       ccall.add_argument (cexpr);
-                                                       cexpr = ccall;
-                                               }
-                                       } else if (param.type_reference.data_type is Callback) {
-                                               cexpr = new CCodeCastExpression (cexpr, param.type_reference.data_type.get_cname ());
-                                       } else if (param.type_reference.data_type == null
-                                                  && arg.static_type.data_type is Struct) {
-                                               /* convert integer to pointer if this is a generic method parameter */
-                                               var st = (Struct) arg.static_type.data_type;
-                                               if (st == bool_type.data_type || st.is_integer_type ()) {
-                                                       var cconv = new CCodeFunctionCall (new CCodeIdentifier ("GINT_TO_POINTER"));
-                                                       cconv.add_argument (cexpr);
-                                                       cexpr = cconv;
-                                               }
-                                       }
-                               }
-                       }
-                                       
-                       ccall.add_argument (cexpr);
-                       i++;
-                       
-                       if (params_it != null) {
-                               params_it = params_it.next;
-                       }
-               }
-               while (params_it != null) {
-                       var param = (FormalParameter) params_it.data;
-                       
-                       if (param.ellipsis) {
-                               ellipsis = true;
-                               break;
-                       }
-                       
-                       if (param.default_expression == null) {
-                               Report.error (expr.source_reference, "no default expression for argument %d".printf (i));
-                               return;
-                       }
-                       
-                       /* evaluate default expression here as the code
-                        * generator might not have visited the formal
-                        * parameter yet */
-                       param.default_expression.accept (this);
-               
-                       if (!param.no_array_length && param.type_reference != null &&
-                           param.type_reference.data_type is Array) {
-                               var arr = (Array) param.type_reference.data_type;
-                               for (int dim = 1; dim <= arr.rank; dim++) {
-                                       ccall.add_argument (get_array_length_cexpression (param.default_expression, dim));
-                               }
-                       }
-
-                       ccall.add_argument ((CCodeExpression) param.default_expression.ccodenode);
-                       i++;
-               
-                       params_it = params_it.next;
-               }
-               
-               if (m != null && m.instance && m.instance_last) {
-                       ccall.add_argument (instance);
-               } else if (ellipsis) {
-                       /* ensure variable argument list ends with NULL
-                        * except when using printf-style arguments */
-                       if (m == null || !m.printf_format) {
-                               ccall.add_argument (new CCodeConstant ("NULL"));
-                       }
-               }
-               
-               if (m != null && m.instance && m.returns_modified_pointer) {
-                       expr.ccodenode = new CCodeAssignment (instance, ccall);
-               } else {
-                       /* cast pointer to actual type if this is a generic method return value */
-                       if (m != null && m.return_type.type_parameter != null && expr.static_type.data_type != null) {
-                               if (expr.static_type.data_type is Struct) {
-                                       var st = (Struct) expr.static_type.data_type;
-                                       if (st == uint_type.data_type) {
-                                               var cconv = new CCodeFunctionCall (new CCodeIdentifier ("GPOINTER_TO_UINT"));
-                                               cconv.add_argument (ccall);
-                                               ccall = cconv;
-                                       } else if (st == bool_type.data_type || st.is_integer_type ()) {
-                                               var cconv = new CCodeFunctionCall (new CCodeIdentifier ("GPOINTER_TO_INT"));
-                                               cconv.add_argument (ccall);
-                                               ccall = cconv;
-                                       }
-                               }
-                       }
-
-                       expr.ccodenode = ccall;
-               
-                       visit_expression (expr);
-               }
-               
-               if (m is ArrayResizeMethod) {
-                       // FIXME: size expression must not be evaluated twice at runtime (potential side effects)
-                       var new_size = (CCodeExpression) ((CodeNode) expr.get_argument_list ().data).ccodenode;
-
-                       var temp_decl = get_temp_variable_declarator (int_type);
-                       var temp_ref = new CCodeIdentifier (temp_decl.name);
-
-                       temp_vars.prepend (temp_decl);
-
-                       /* memset needs string.h */
-                       string_h_needed = true;
-
-                       var clen = get_array_length_cexpression (ma.inner, 1);
-                       var celems = (CCodeExpression)ma.inner.ccodenode;
-                       var csizeof = new CCodeIdentifier ("sizeof (%s)".printf (ma.inner.static_type.data_type.get_cname ()));
-                       var cdelta = new CCodeParenthesizedExpression (new CCodeBinaryExpression (CCodeBinaryOperator.MINUS, temp_ref, clen));
-                       var ccheck = new CCodeBinaryExpression (CCodeBinaryOperator.GREATER_THAN, temp_ref, clen);
-
-                       var czero = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
-                       czero.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, celems, clen));
-                       czero.add_argument (new CCodeConstant ("0"));
-                       czero.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, csizeof, cdelta));
-
-                       var ccomma = new CCodeCommaExpression ();
-                       ccomma.append_expression (new CCodeAssignment (temp_ref, new_size));
-                       ccomma.append_expression ((CCodeExpression) expr.ccodenode);
-                       ccomma.append_expression (new CCodeConditionalExpression (ccheck, czero, new CCodeConstant ("NULL")));
-                       ccomma.append_expression (new CCodeAssignment (get_array_length_cexpression (ma.inner, 1), temp_ref));
-
-                       expr.ccodenode = ccomma;
-               }
-       }
-       
        public override void visit_element_access (ElementAccess! expr)
        {
                List<weak Expression> indices = expr.get_indices ();
@@ -3894,284 +1983,4 @@ public class Vala.CodeGenerator : CodeVisitor {
        public override void visit_end_lambda_expression (LambdaExpression! l) {
                l.ccodenode = new CCodeIdentifier (l.method.get_cname ());
        }
-
-       public override void visit_end_assignment (Assignment! a) {
-               MemberAccess ma = null;
-               
-               if (a.left is MemberAccess) {
-                       ma = (MemberAccess)a.left;
-               }
-
-               if (a.left.symbol_reference != null && a.left.symbol_reference.node is Property) {
-                       var prop = (Property) a.left.symbol_reference.node;
-                       
-                       if (current_class != null && ma.inner == null && in_creation_method) {
-                               // this property is used as a construction parameter
-                               var cpointer = new CCodeIdentifier ("__params_it");
-                               
-                               var ccomma = new CCodeCommaExpression ();
-                               // set name in array for current parameter
-                               var cnamemember = new CCodeMemberAccess.pointer (cpointer, "name");
-                               var cnameassign = new CCodeAssignment (cnamemember, prop.get_canonical_cconstant ());
-                               ccomma.append_expression (cnameassign);
-                               
-                               var gvaluearg = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeMemberAccess.pointer (cpointer, "value"));
-                               
-                               // initialize GValue in array for current parameter
-                               var cvalueinit = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
-                               cvalueinit.add_argument (gvaluearg);
-                               cvalueinit.add_argument (new CCodeIdentifier (prop.type_reference.data_type.get_type_id ()));
-                               ccomma.append_expression (cvalueinit);
-                               
-                               // set GValue for current parameter
-                               var cvalueset = new CCodeFunctionCall (get_value_setter_function (prop.type_reference));
-                               cvalueset.add_argument (gvaluearg);
-                               cvalueset.add_argument ((CCodeExpression) a.right.ccodenode);
-                               ccomma.append_expression (cvalueset);
-                               
-                               // move pointer to next parameter in array
-                               ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, cpointer));
-                               
-                               a.ccodenode = ccomma;
-                       } else {
-                               ref CCodeExpression cexpr = (CCodeExpression) a.right.ccodenode;
-                               
-                               if (!prop.no_accessor_method
-                                   && prop.type_reference.data_type != null
-                                   && prop.type_reference.data_type.is_reference_type ()
-                                   && a.right.static_type.data_type != null
-                                   && prop.type_reference.data_type != a.right.static_type.data_type) {
-                                       /* cast is necessary */
-                                       var ccast = new CCodeFunctionCall (new CCodeIdentifier (prop.type_reference.data_type.get_upper_case_cname (null)));
-                                       ccast.add_argument (cexpr);
-                                       cexpr = ccast;
-                               }
-                               
-                               if (a.operator != AssignmentOperator.SIMPLE) {
-                                       CCodeBinaryOperator cop;
-                                       if (a.operator == AssignmentOperator.BITWISE_OR) {
-                                               cop = CCodeBinaryOperator.BITWISE_OR;
-                                       } else if (a.operator == AssignmentOperator.BITWISE_AND) {
-                                               cop = CCodeBinaryOperator.BITWISE_AND;
-                                       } else if (a.operator == AssignmentOperator.BITWISE_XOR) {
-                                               cop = CCodeBinaryOperator.BITWISE_XOR;
-                                       } else if (a.operator == AssignmentOperator.ADD) {
-                                               cop = CCodeBinaryOperator.PLUS;
-                                       } else if (a.operator == AssignmentOperator.SUB) {
-                                               cop = CCodeBinaryOperator.MINUS;
-                                       } else if (a.operator == AssignmentOperator.MUL) {
-                                               cop = CCodeBinaryOperator.MUL;
-                                       } else if (a.operator == AssignmentOperator.DIV) {
-                                               cop = CCodeBinaryOperator.DIV;
-                                       } else if (a.operator == AssignmentOperator.PERCENT) {
-                                               cop = CCodeBinaryOperator.MOD;
-                                       } else if (a.operator == AssignmentOperator.SHIFT_LEFT) {
-                                               cop = CCodeBinaryOperator.SHIFT_LEFT;
-                                       } else if (a.operator == AssignmentOperator.SHIFT_RIGHT) {
-                                               cop = CCodeBinaryOperator.SHIFT_RIGHT;
-                                       }
-                                       cexpr = new CCodeBinaryExpression (cop, (CCodeExpression) a.left.ccodenode, new CCodeParenthesizedExpression (cexpr));
-                               }
-                               
-                               var ccall = get_property_set_call (prop, ma, cexpr);
-                               
-                               // assignments are expressions, so return the current property value
-                               var ccomma = new CCodeCommaExpression ();
-                               ccomma.append_expression (ccall); // update property
-                               ccomma.append_expression ((CCodeExpression) ma.ccodenode); // current property value
-                               
-                               a.ccodenode = ccomma;
-                       }
-               } else if (a.left.symbol_reference != null && a.left.symbol_reference.node is Signal) {
-                       var sig = (Signal) a.left.symbol_reference.node;
-                       
-                       var m = (Method) a.right.symbol_reference.node;
-
-                       string connect_func;
-                       bool disconnect = false;
-
-                       if (a.operator == AssignmentOperator.ADD) {
-                               connect_func = "g_signal_connect_object";
-                               if (!m.instance) {
-                                       connect_func = "g_signal_connect";
-                               }
-                       } else if (a.operator == AssignmentOperator.SUB) {
-                               connect_func = "g_signal_handlers_disconnect_matched";
-                               disconnect = true;
-                       } else {
-                               a.error = true;
-                               Report.error (a.source_reference, "Specified compound assignment type for signals not supported.");
-                               return;
-                       }
-
-                       var ccall = new CCodeFunctionCall (new CCodeIdentifier (connect_func));
-               
-                       if (ma.inner != null) {
-                               ccall.add_argument ((CCodeExpression) ma.inner.ccodenode);
-                       } else {
-                               ccall.add_argument (new CCodeIdentifier ("self"));
-                       }
-
-                       if (!disconnect) {
-                               ccall.add_argument (sig.get_canonical_cconstant ());
-                       } else {
-                               ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA"));
-                               
-                               // get signal id
-                               var ccomma = new CCodeCommaExpression ();
-                               var temp_decl = get_temp_variable_declarator (uint_type);
-                               temp_vars.prepend (temp_decl);
-                               var parse_call = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_parse_name"));
-                               parse_call.add_argument (sig.get_canonical_cconstant ());
-                               var decl_type = (DataType) sig.symbol.parent_symbol.node;
-                               parse_call.add_argument (new CCodeIdentifier (decl_type.get_type_id ()));
-                               parse_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_decl.name)));
-                               parse_call.add_argument (new CCodeConstant ("NULL"));
-                               parse_call.add_argument (new CCodeConstant ("FALSE"));
-                               ccomma.append_expression (parse_call);
-                               ccomma.append_expression (new CCodeIdentifier (temp_decl.name));
-                               
-                               ccall.add_argument (ccomma);
-
-                               ccall.add_argument (new CCodeConstant ("0"));
-                               ccall.add_argument (new CCodeConstant ("NULL"));
-                       }
-
-                       ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier (m.get_cname ()), "GCallback"));
-
-                       if (m.instance) {
-                               if (a.right is MemberAccess) {
-                                       var right_ma = (MemberAccess) a.right;
-                                       if (right_ma.inner != null) {
-                                               ccall.add_argument ((CCodeExpression) right_ma.inner.ccodenode);
-                                       } else {
-                                               ccall.add_argument (new CCodeIdentifier ("self"));
-                                       }
-                               } else if (a.right is LambdaExpression) {
-                                       ccall.add_argument (new CCodeIdentifier ("self"));
-                               }
-                               if (!disconnect) {
-                                       ccall.add_argument (new CCodeConstant ("0"));
-                               }
-                       } else {
-                               ccall.add_argument (new CCodeConstant ("NULL"));
-                       }
-                       
-                       a.ccodenode = ccall;
-               } else {
-                       /* explicitly use strong reference as ccast gets
-                        * unrefed at end of inner block
-                        */
-                       ref CCodeExpression rhs = (CCodeExpression) a.right.ccodenode;
-                       
-                       if (a.left.static_type.data_type != null
-                           && a.right.static_type.data_type != null
-                           && a.left.static_type.data_type.is_reference_type ()
-                           && a.right.static_type.data_type != a.left.static_type.data_type) {
-                               var ccast = new CCodeFunctionCall (new CCodeIdentifier (a.left.static_type.data_type.get_upper_case_cname (null)));
-                               ccast.add_argument (rhs);
-                               rhs = ccast;
-                       }
-                       
-                       bool unref_old = (memory_management && a.left.static_type.takes_ownership);
-                       bool array = false;
-                       if (a.left.static_type.data_type is Array) {
-                               array = !(get_array_length_cexpression (a.left, 1) is CCodeConstant);
-                       }
-                       
-                       if (unref_old || array) {
-                               var ccomma = new CCodeCommaExpression ();
-                               
-                               var temp_decl = get_temp_variable_declarator (a.left.static_type);
-                               temp_vars.prepend (temp_decl);
-                               ccomma.append_expression (new CCodeAssignment (new CCodeIdentifier (temp_decl.name), rhs));
-                               if (unref_old) {
-                                       /* unref old value */
-                                       ccomma.append_expression (get_unref_expression ((CCodeExpression) a.left.ccodenode, a.left.static_type));
-                               }
-                               
-                               if (array) {
-                                       var lhs_array_len = get_array_length_cexpression (a.left, 1);
-                                       var rhs_array_len = get_array_length_cexpression (a.right, 1);
-                                       ccomma.append_expression (new CCodeAssignment (lhs_array_len, rhs_array_len));
-                               }
-                               
-                               ccomma.append_expression (new CCodeIdentifier (temp_decl.name));
-                               
-                               rhs = ccomma;
-                       }
-                       
-                       var cop = CCodeAssignmentOperator.SIMPLE;
-                       if (a.operator == AssignmentOperator.BITWISE_OR) {
-                               cop = CCodeAssignmentOperator.BITWISE_OR;
-                       } else if (a.operator == AssignmentOperator.BITWISE_AND) {
-                               cop = CCodeAssignmentOperator.BITWISE_AND;
-                       } else if (a.operator == AssignmentOperator.BITWISE_XOR) {
-                               cop = CCodeAssignmentOperator.BITWISE_XOR;
-                       } else if (a.operator == AssignmentOperator.ADD) {
-                               cop = CCodeAssignmentOperator.ADD;
-                       } else if (a.operator == AssignmentOperator.SUB) {
-                               cop = CCodeAssignmentOperator.SUB;
-                       } else if (a.operator == AssignmentOperator.MUL) {
-                               cop = CCodeAssignmentOperator.MUL;
-                       } else if (a.operator == AssignmentOperator.DIV) {
-                               cop = CCodeAssignmentOperator.DIV;
-                       } else if (a.operator == AssignmentOperator.PERCENT) {
-                               cop = CCodeAssignmentOperator.PERCENT;
-                       } else if (a.operator == AssignmentOperator.SHIFT_LEFT) {
-                               cop = CCodeAssignmentOperator.SHIFT_LEFT;
-                       } else if (a.operator == AssignmentOperator.SHIFT_RIGHT) {
-                               cop = CCodeAssignmentOperator.SHIFT_RIGHT;
-                       }
-               
-                       a.ccodenode = new CCodeAssignment ((CCodeExpression) a.left.ccodenode, rhs, cop);
-               }
-       }
-       
-       private ref CCodeFunctionCall get_property_set_call (Property! prop, MemberAccess! ma, CCodeExpression! cexpr) {
-               var cl = (Class) prop.symbol.parent_symbol.node;
-               var set_func = "g_object_set";
-               
-               if (!prop.no_accessor_method) {
-                       set_func = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
-               }
-               
-               var ccall = new CCodeFunctionCall (new CCodeIdentifier (set_func));
-
-               /* target instance is first argument */
-               ref CCodeExpression instance;
-               var req_cast = false;
-
-               if (ma.inner == null) {
-                       instance = new CCodeIdentifier ("self");
-                       /* require casts for inherited properties */
-                       req_cast = (prop.symbol.parent_symbol != current_type_symbol);
-               } else {
-                       instance = (CCodeExpression) ma.inner.ccodenode;
-                       /* require casts if the type of the used instance is
-                        * different than the type which declared the property */
-                       req_cast = prop.symbol.parent_symbol.node != ma.inner.static_type.data_type;
-               }
-               
-               if (req_cast && ((DataType) prop.symbol.parent_symbol.node).is_reference_type ()) {
-                       var ccast = new CCodeFunctionCall (new CCodeIdentifier (((DataType) prop.symbol.parent_symbol.node).get_upper_case_cname (null)));
-                       ccast.add_argument (instance);
-                       instance = ccast;
-               }
-
-               ccall.add_argument (instance);
-
-               if (prop.no_accessor_method) {
-                       /* property name is second argument of g_object_set */
-                       ccall.add_argument (prop.get_canonical_cconstant ());
-               }
-                       
-               ccall.add_argument (cexpr);
-               
-               if (prop.no_accessor_method) {
-                       ccall.add_argument (new CCodeConstant ("NULL"));
-               }
-
-               return ccall;
-       }
 }
diff --git a/gobject/valacodegeneratorassignment.vala b/gobject/valacodegeneratorassignment.vala
new file mode 100644 (file)
index 0000000..d51470c
--- /dev/null
@@ -0,0 +1,307 @@
+/* valacodegeneratorassignment.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>
+ */
+
+using GLib;
+
+public class Vala.CodeGenerator {
+       public override void visit_end_assignment (Assignment! a) {
+               MemberAccess ma = null;
+               
+               if (a.left is MemberAccess) {
+                       ma = (MemberAccess)a.left;
+               }
+
+               if (a.left.symbol_reference != null && a.left.symbol_reference.node is Property) {
+                       var prop = (Property) a.left.symbol_reference.node;
+                       
+                       if (current_class != null && ma.inner == null && in_creation_method) {
+                               // this property is used as a construction parameter
+                               var cpointer = new CCodeIdentifier ("__params_it");
+                               
+                               var ccomma = new CCodeCommaExpression ();
+                               // set name in array for current parameter
+                               var cnamemember = new CCodeMemberAccess.pointer (cpointer, "name");
+                               var cnameassign = new CCodeAssignment (cnamemember, prop.get_canonical_cconstant ());
+                               ccomma.append_expression (cnameassign);
+                               
+                               var gvaluearg = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeMemberAccess.pointer (cpointer, "value"));
+                               
+                               // initialize GValue in array for current parameter
+                               var cvalueinit = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
+                               cvalueinit.add_argument (gvaluearg);
+                               cvalueinit.add_argument (new CCodeIdentifier (prop.type_reference.data_type.get_type_id ()));
+                               ccomma.append_expression (cvalueinit);
+                               
+                               // set GValue for current parameter
+                               var cvalueset = new CCodeFunctionCall (get_value_setter_function (prop.type_reference));
+                               cvalueset.add_argument (gvaluearg);
+                               cvalueset.add_argument ((CCodeExpression) a.right.ccodenode);
+                               ccomma.append_expression (cvalueset);
+                               
+                               // move pointer to next parameter in array
+                               ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, cpointer));
+                               
+                               a.ccodenode = ccomma;
+                       } else {
+                               ref CCodeExpression cexpr = (CCodeExpression) a.right.ccodenode;
+                               
+                               if (!prop.no_accessor_method
+                                   && prop.type_reference.data_type != null
+                                   && prop.type_reference.data_type.is_reference_type ()
+                                   && a.right.static_type.data_type != null
+                                   && prop.type_reference.data_type != a.right.static_type.data_type) {
+                                       /* cast is necessary */
+                                       var ccast = new CCodeFunctionCall (new CCodeIdentifier (prop.type_reference.data_type.get_upper_case_cname (null)));
+                                       ccast.add_argument (cexpr);
+                                       cexpr = ccast;
+                               }
+                               
+                               if (a.operator != AssignmentOperator.SIMPLE) {
+                                       CCodeBinaryOperator cop;
+                                       if (a.operator == AssignmentOperator.BITWISE_OR) {
+                                               cop = CCodeBinaryOperator.BITWISE_OR;
+                                       } else if (a.operator == AssignmentOperator.BITWISE_AND) {
+                                               cop = CCodeBinaryOperator.BITWISE_AND;
+                                       } else if (a.operator == AssignmentOperator.BITWISE_XOR) {
+                                               cop = CCodeBinaryOperator.BITWISE_XOR;
+                                       } else if (a.operator == AssignmentOperator.ADD) {
+                                               cop = CCodeBinaryOperator.PLUS;
+                                       } else if (a.operator == AssignmentOperator.SUB) {
+                                               cop = CCodeBinaryOperator.MINUS;
+                                       } else if (a.operator == AssignmentOperator.MUL) {
+                                               cop = CCodeBinaryOperator.MUL;
+                                       } else if (a.operator == AssignmentOperator.DIV) {
+                                               cop = CCodeBinaryOperator.DIV;
+                                       } else if (a.operator == AssignmentOperator.PERCENT) {
+                                               cop = CCodeBinaryOperator.MOD;
+                                       } else if (a.operator == AssignmentOperator.SHIFT_LEFT) {
+                                               cop = CCodeBinaryOperator.SHIFT_LEFT;
+                                       } else if (a.operator == AssignmentOperator.SHIFT_RIGHT) {
+                                               cop = CCodeBinaryOperator.SHIFT_RIGHT;
+                                       }
+                                       cexpr = new CCodeBinaryExpression (cop, (CCodeExpression) a.left.ccodenode, new CCodeParenthesizedExpression (cexpr));
+                               }
+                               
+                               var ccall = get_property_set_call (prop, ma, cexpr);
+                               
+                               // assignments are expressions, so return the current property value
+                               var ccomma = new CCodeCommaExpression ();
+                               ccomma.append_expression (ccall); // update property
+                               ccomma.append_expression ((CCodeExpression) ma.ccodenode); // current property value
+                               
+                               a.ccodenode = ccomma;
+                       }
+               } else if (a.left.symbol_reference != null && a.left.symbol_reference.node is Signal) {
+                       var sig = (Signal) a.left.symbol_reference.node;
+                       
+                       var m = (Method) a.right.symbol_reference.node;
+
+                       string connect_func;
+                       bool disconnect = false;
+
+                       if (a.operator == AssignmentOperator.ADD) {
+                               connect_func = "g_signal_connect_object";
+                               if (!m.instance) {
+                                       connect_func = "g_signal_connect";
+                               }
+                       } else if (a.operator == AssignmentOperator.SUB) {
+                               connect_func = "g_signal_handlers_disconnect_matched";
+                               disconnect = true;
+                       } else {
+                               a.error = true;
+                               Report.error (a.source_reference, "Specified compound assignment type for signals not supported.");
+                               return;
+                       }
+
+                       var ccall = new CCodeFunctionCall (new CCodeIdentifier (connect_func));
+               
+                       if (ma.inner != null) {
+                               ccall.add_argument ((CCodeExpression) ma.inner.ccodenode);
+                       } else {
+                               ccall.add_argument (new CCodeIdentifier ("self"));
+                       }
+
+                       if (!disconnect) {
+                               ccall.add_argument (sig.get_canonical_cconstant ());
+                       } else {
+                               ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA"));
+                               
+                               // get signal id
+                               var ccomma = new CCodeCommaExpression ();
+                               var temp_decl = get_temp_variable_declarator (uint_type);
+                               temp_vars.prepend (temp_decl);
+                               var parse_call = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_parse_name"));
+                               parse_call.add_argument (sig.get_canonical_cconstant ());
+                               var decl_type = (DataType) sig.symbol.parent_symbol.node;
+                               parse_call.add_argument (new CCodeIdentifier (decl_type.get_type_id ()));
+                               parse_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_decl.name)));
+                               parse_call.add_argument (new CCodeConstant ("NULL"));
+                               parse_call.add_argument (new CCodeConstant ("FALSE"));
+                               ccomma.append_expression (parse_call);
+                               ccomma.append_expression (new CCodeIdentifier (temp_decl.name));
+                               
+                               ccall.add_argument (ccomma);
+
+                               ccall.add_argument (new CCodeConstant ("0"));
+                               ccall.add_argument (new CCodeConstant ("NULL"));
+                       }
+
+                       ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier (m.get_cname ()), "GCallback"));
+
+                       if (m.instance) {
+                               if (a.right is MemberAccess) {
+                                       var right_ma = (MemberAccess) a.right;
+                                       if (right_ma.inner != null) {
+                                               ccall.add_argument ((CCodeExpression) right_ma.inner.ccodenode);
+                                       } else {
+                                               ccall.add_argument (new CCodeIdentifier ("self"));
+                                       }
+                               } else if (a.right is LambdaExpression) {
+                                       ccall.add_argument (new CCodeIdentifier ("self"));
+                               }
+                               if (!disconnect) {
+                                       ccall.add_argument (new CCodeConstant ("0"));
+                               }
+                       } else {
+                               ccall.add_argument (new CCodeConstant ("NULL"));
+                       }
+                       
+                       a.ccodenode = ccall;
+               } else {
+                       /* explicitly use strong reference as ccast gets
+                        * unrefed at end of inner block
+                        */
+                       ref CCodeExpression rhs = (CCodeExpression) a.right.ccodenode;
+                       
+                       if (a.left.static_type.data_type != null
+                           && a.right.static_type.data_type != null
+                           && a.left.static_type.data_type.is_reference_type ()
+                           && a.right.static_type.data_type != a.left.static_type.data_type) {
+                               var ccast = new CCodeFunctionCall (new CCodeIdentifier (a.left.static_type.data_type.get_upper_case_cname (null)));
+                               ccast.add_argument (rhs);
+                               rhs = ccast;
+                       }
+                       
+                       bool unref_old = (memory_management && a.left.static_type.takes_ownership);
+                       bool array = false;
+                       if (a.left.static_type.data_type is Array) {
+                               array = !(get_array_length_cexpression (a.left, 1) is CCodeConstant);
+                       }
+                       
+                       if (unref_old || array) {
+                               var ccomma = new CCodeCommaExpression ();
+                               
+                               var temp_decl = get_temp_variable_declarator (a.left.static_type);
+                               temp_vars.prepend (temp_decl);
+                               ccomma.append_expression (new CCodeAssignment (new CCodeIdentifier (temp_decl.name), rhs));
+                               if (unref_old) {
+                                       /* unref old value */
+                                       ccomma.append_expression (get_unref_expression ((CCodeExpression) a.left.ccodenode, a.left.static_type));
+                               }
+                               
+                               if (array) {
+                                       var lhs_array_len = get_array_length_cexpression (a.left, 1);
+                                       var rhs_array_len = get_array_length_cexpression (a.right, 1);
+                                       ccomma.append_expression (new CCodeAssignment (lhs_array_len, rhs_array_len));
+                               }
+                               
+                               ccomma.append_expression (new CCodeIdentifier (temp_decl.name));
+                               
+                               rhs = ccomma;
+                       }
+                       
+                       var cop = CCodeAssignmentOperator.SIMPLE;
+                       if (a.operator == AssignmentOperator.BITWISE_OR) {
+                               cop = CCodeAssignmentOperator.BITWISE_OR;
+                       } else if (a.operator == AssignmentOperator.BITWISE_AND) {
+                               cop = CCodeAssignmentOperator.BITWISE_AND;
+                       } else if (a.operator == AssignmentOperator.BITWISE_XOR) {
+                               cop = CCodeAssignmentOperator.BITWISE_XOR;
+                       } else if (a.operator == AssignmentOperator.ADD) {
+                               cop = CCodeAssignmentOperator.ADD;
+                       } else if (a.operator == AssignmentOperator.SUB) {
+                               cop = CCodeAssignmentOperator.SUB;
+                       } else if (a.operator == AssignmentOperator.MUL) {
+                               cop = CCodeAssignmentOperator.MUL;
+                       } else if (a.operator == AssignmentOperator.DIV) {
+                               cop = CCodeAssignmentOperator.DIV;
+                       } else if (a.operator == AssignmentOperator.PERCENT) {
+                               cop = CCodeAssignmentOperator.PERCENT;
+                       } else if (a.operator == AssignmentOperator.SHIFT_LEFT) {
+                               cop = CCodeAssignmentOperator.SHIFT_LEFT;
+                       } else if (a.operator == AssignmentOperator.SHIFT_RIGHT) {
+                               cop = CCodeAssignmentOperator.SHIFT_RIGHT;
+                       }
+               
+                       a.ccodenode = new CCodeAssignment ((CCodeExpression) a.left.ccodenode, rhs, cop);
+               }
+       }
+
+       private ref CCodeFunctionCall get_property_set_call (Property! prop, MemberAccess! ma, CCodeExpression! cexpr) {
+               var cl = (Class) prop.symbol.parent_symbol.node;
+               var set_func = "g_object_set";
+               
+               if (!prop.no_accessor_method) {
+                       set_func = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
+               }
+               
+               var ccall = new CCodeFunctionCall (new CCodeIdentifier (set_func));
+
+               /* target instance is first argument */
+               ref CCodeExpression instance;
+               var req_cast = false;
+
+               if (ma.inner == null) {
+                       instance = new CCodeIdentifier ("self");
+                       /* require casts for inherited properties */
+                       req_cast = (prop.symbol.parent_symbol != current_type_symbol);
+               } else {
+                       instance = (CCodeExpression) ma.inner.ccodenode;
+                       /* require casts if the type of the used instance is
+                        * different than the type which declared the property */
+                       req_cast = prop.symbol.parent_symbol.node != ma.inner.static_type.data_type;
+               }
+               
+               if (req_cast && ((DataType) prop.symbol.parent_symbol.node).is_reference_type ()) {
+                       var ccast = new CCodeFunctionCall (new CCodeIdentifier (((DataType) prop.symbol.parent_symbol.node).get_upper_case_cname (null)));
+                       ccast.add_argument (instance);
+                       instance = ccast;
+               }
+
+               ccall.add_argument (instance);
+
+               if (prop.no_accessor_method) {
+                       /* property name is second argument of g_object_set */
+                       ccall.add_argument (prop.get_canonical_cconstant ());
+               }
+                       
+               ccall.add_argument (cexpr);
+               
+               if (prop.no_accessor_method) {
+                       ccall.add_argument (new CCodeConstant ("NULL"));
+               }
+
+               return ccall;
+       }
+}
+
diff --git a/gobject/valacodegeneratorclass.vala b/gobject/valacodegeneratorclass.vala
new file mode 100644 (file)
index 0000000..39947b8
--- /dev/null
@@ -0,0 +1,506 @@
+/* valacodegeneratorclass.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>
+ */
+
+using GLib;
+
+public class Vala.CodeGenerator {
+       public override void visit_begin_class (Class! cl) {
+               current_symbol = cl.symbol;
+               current_type_symbol = cl.symbol;
+               current_class = cl;
+
+               if (cl.is_static) {
+                       return;
+               }
+
+               instance_struct = new CCodeStruct ("_%s".printf (cl.get_cname ()));
+               type_struct = new CCodeStruct ("_%sClass".printf (cl.get_cname ()));
+               instance_priv_struct = new CCodeStruct ("_%sPrivate".printf (cl.get_cname ()));
+               prop_enum = new CCodeEnum ();
+               prop_enum.add_value ("%s_DUMMY_PROPERTY".printf (cl.get_upper_case_cname (null)), null);
+               instance_init_fragment = new CCodeFragment ();
+               instance_dispose_fragment = new CCodeFragment ();
+               
+               
+               header_type_declaration.append (new CCodeNewline ());
+               var macro = "(%s_get_type ())".printf (cl.get_lower_case_cname (null));
+               header_type_declaration.append (new CCodeMacroReplacement (cl.get_upper_case_cname ("TYPE_"), macro));
+
+               macro = "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
+               header_type_declaration.append (new CCodeMacroReplacement ("%s(obj)".printf (cl.get_upper_case_cname (null)), macro));
+
+               macro = "(G_TYPE_CHECK_CLASS_CAST ((klass), %s, %sClass))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
+               header_type_declaration.append (new CCodeMacroReplacement ("%s_CLASS(klass)".printf (cl.get_upper_case_cname (null)), macro));
+
+               macro = "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (cl.get_upper_case_cname ("TYPE_"));
+               header_type_declaration.append (new CCodeMacroReplacement ("%s(obj)".printf (cl.get_upper_case_cname ("IS_")), macro));
+
+               macro = "(G_TYPE_CHECK_CLASS_TYPE ((klass), %s))".printf (cl.get_upper_case_cname ("TYPE_"));
+               header_type_declaration.append (new CCodeMacroReplacement ("%s_CLASS(klass)".printf (cl.get_upper_case_cname ("IS_")), macro));
+
+               macro = "(G_TYPE_INSTANCE_GET_CLASS ((obj), %s, %sClass))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
+               header_type_declaration.append (new CCodeMacroReplacement ("%s_GET_CLASS(obj)".printf (cl.get_upper_case_cname (null)), macro));
+               header_type_declaration.append (new CCodeNewline ());
+
+
+               if (cl.source_reference.file.cycle == null) {
+                       header_type_declaration.append (new CCodeTypeDefinition ("struct %s".printf (instance_struct.name), new CCodeVariableDeclarator (cl.get_cname ())));
+                       header_type_declaration.append (new CCodeTypeDefinition ("struct %s".printf (type_struct.name), new CCodeVariableDeclarator ("%sClass".printf (cl.get_cname ()))));
+               }
+               header_type_declaration.append (new CCodeTypeDefinition ("struct %s".printf (instance_priv_struct.name), new CCodeVariableDeclarator ("%sPrivate".printf (cl.get_cname ()))));
+               
+               instance_struct.add_field (cl.base_class.get_cname (), "parent");
+               instance_struct.add_field ("%sPrivate *".printf (cl.get_cname ()), "priv");
+               type_struct.add_field ("%sClass".printf (cl.base_class.get_cname ()), "parent");
+
+               if (cl.source_reference.comment != null) {
+                       header_type_definition.append (new CCodeComment (cl.source_reference.comment));
+               }
+               header_type_definition.append (instance_struct);
+               header_type_definition.append (type_struct);
+               source_type_member_declaration.append (instance_priv_struct);
+               macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
+               source_type_member_declaration.append (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), macro));
+               source_type_member_declaration.append (prop_enum);
+       }
+       
+       public override void visit_end_class (Class! cl) {
+               if (!cl.is_static) {
+                       add_get_property_function (cl);
+                       add_set_property_function (cl);
+                       add_class_init_function (cl);
+                       
+                       foreach (TypeReference base_type in cl.get_base_types ()) {
+                               if (base_type.data_type is Interface) {
+                                       add_interface_init_function (cl, (Interface) base_type.data_type);
+                               }
+                       }
+                       
+                       add_instance_init_function (cl);
+                       if (memory_management && cl.get_fields () != null) {
+                               add_dispose_function (cl);
+                       }
+                       
+                       var type_fun = new ClassRegisterFunction (cl);
+                       type_fun.init_from_type (in_plugin);
+                       header_type_member_declaration.append (type_fun.get_declaration ());
+                       source_type_member_definition.append (type_fun.get_definition ());
+                       
+                       if (in_plugin) {
+                               // FIXME resolve potential dependency issues, i.e. base types have to be registered before derived types
+                               var register_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_register_type".printf (cl.get_lower_case_cname (null))));
+                               register_call.add_argument (new CCodeIdentifier (module_init_param_name));
+                               module_init_fragment.append (new CCodeExpressionStatement (register_call));
+                       }
+               }
+
+               current_type_symbol = null;
+               current_class = null;
+               instance_dispose_fragment = null;
+       }
+       
+       private void add_class_init_function (Class! cl) {
+               var class_init = new CCodeFunction ("%s_class_init".printf (cl.get_lower_case_cname (null)), "void");
+               class_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
+               class_init.modifiers = CCodeModifiers.STATIC;
+               
+               var init_block = new CCodeBlock ();
+               class_init.block = init_block;
+               
+               ref CCodeFunctionCall ccall;
+               
+               /* save pointer to parent class */
+               var parent_decl = new CCodeDeclaration ("gpointer");
+               var parent_var_decl = new CCodeVariableDeclarator ("%s_parent_class".printf (cl.get_lower_case_cname (null)));
+               parent_var_decl.initializer = new CCodeConstant ("NULL");
+               parent_decl.add_declarator (parent_var_decl);
+               parent_decl.modifiers = CCodeModifiers.STATIC;
+               source_type_member_declaration.append (parent_decl);
+               ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek_parent"));
+               ccall.add_argument (new CCodeIdentifier ("klass"));
+               var parent_assignment = new CCodeAssignment (new CCodeIdentifier ("%s_parent_class".printf (cl.get_lower_case_cname (null))), ccall);
+               init_block.add_statement (new CCodeExpressionStatement (parent_assignment));
+               
+               /* add struct for private fields */
+               if (cl.has_private_fields) {
+                       ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_add_private"));
+                       ccall.add_argument (new CCodeIdentifier ("klass"));
+                       ccall.add_argument (new CCodeConstant ("sizeof (%sPrivate)".printf (cl.get_cname ())));
+                       init_block.add_statement (new CCodeExpressionStatement (ccall));
+               }
+               
+               /* set property handlers */
+               ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
+               ccall.add_argument (new CCodeIdentifier ("klass"));
+               init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "get_property"), new CCodeIdentifier ("%s_get_property".printf (cl.get_lower_case_cname (null))))));
+               init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "set_property"), new CCodeIdentifier ("%s_set_property".printf (cl.get_lower_case_cname (null))))));
+               
+               /* set constructor */
+               if (cl.constructor != null) {
+                       var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
+                       ccast.add_argument (new CCodeIdentifier ("klass"));
+                       init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "constructor"), new CCodeIdentifier ("%s_constructor".printf (cl.get_lower_case_cname (null))))));
+               }
+
+               /* set dispose function */
+               if (memory_management && cl.get_fields () != null) {
+                       var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
+                       ccast.add_argument (new CCodeIdentifier ("klass"));
+                       init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "dispose"), new CCodeIdentifier ("%s_dispose".printf (cl.get_lower_case_cname (null))))));
+               }
+               
+               /* connect overridden methods */
+               var methods = cl.get_methods ();
+               foreach (Method m in methods) {
+                       if (m.base_method == null) {
+                               continue;
+                       }
+                       var base_type = m.base_method.symbol.parent_symbol.node;
+                       
+                       var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (((Class) base_type).get_upper_case_cname (null))));
+                       ccast.add_argument (new CCodeIdentifier ("klass"));
+                       init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, m.name), new CCodeIdentifier (m.get_real_cname ()))));
+               }
+
+               /* create destroy_func properties for generic types */
+               foreach (TypeParameter type_param in cl.get_type_parameters ()) {
+                       string func_name = "%s_destroy_func".printf (type_param.name.down ());
+                       var func_name_constant = new CCodeConstant ("\"%s-destroy-func\"".printf (type_param.name.down ()));
+                       string enum_value = "%s_%s".printf (cl.get_lower_case_cname (null), func_name).up ();
+                       var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_install_property"));
+                       cinst.add_argument (ccall);
+                       cinst.add_argument (new CCodeConstant (enum_value));
+                       var cspec = new CCodeFunctionCall (new CCodeIdentifier ("g_param_spec_pointer"));
+                       cspec.add_argument (func_name_constant);
+                       cspec.add_argument (new CCodeConstant ("\"destroy func\""));
+                       cspec.add_argument (new CCodeConstant ("\"destroy func\""));
+                       cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY"));
+                       cinst.add_argument (cspec);
+                       init_block.add_statement (new CCodeExpressionStatement (cinst));
+                       prop_enum.add_value (enum_value, null);
+
+                       instance_priv_struct.add_field ("GDestroyNotify", func_name);
+               }
+
+               /* create properties */
+               var props = cl.get_properties ();
+               foreach (Property prop in props) {
+                       if (prop.overrides || prop.base_interface_property != null) {
+                               var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_override_property"));
+                               cinst.add_argument (ccall);
+                               cinst.add_argument (new CCodeConstant (prop.get_upper_case_cname ()));
+                               cinst.add_argument (prop.get_canonical_cconstant ());
+                               
+                               init_block.add_statement (new CCodeExpressionStatement (cinst));
+                       } else {
+                               var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_install_property"));
+                               cinst.add_argument (ccall);
+                               cinst.add_argument (new CCodeConstant (prop.get_upper_case_cname ()));
+                               cinst.add_argument (get_param_spec (prop));
+                               
+                               init_block.add_statement (new CCodeExpressionStatement (cinst));
+                       }
+               }
+               
+               /* create signals */
+               foreach (Signal sig in cl.get_signals ()) {
+                       init_block.add_statement (new CCodeExpressionStatement (get_signal_creation (sig, cl)));
+               }
+               
+               source_type_member_definition.append (class_init);
+       }
+       
+       private void add_interface_init_function (Class! cl, Interface! iface) {
+               var iface_init = new CCodeFunction ("%s_%s_interface_init".printf (cl.get_lower_case_cname (null), iface.get_lower_case_cname (null)), "void");
+               iface_init.add_parameter (new CCodeFormalParameter ("iface", "%s *".printf (iface.get_type_cname ())));
+               iface_init.modifiers = CCodeModifiers.STATIC;
+               
+               var init_block = new CCodeBlock ();
+               iface_init.block = init_block;
+               
+               ref CCodeFunctionCall ccall;
+               
+               /* save pointer to parent vtable */
+               string parent_iface_var = "%s_%s_parent_iface".printf (cl.get_lower_case_cname (null), iface.get_lower_case_cname (null));
+               var parent_decl = new CCodeDeclaration (iface.get_type_cname () + "*");
+               var parent_var_decl = new CCodeVariableDeclarator (parent_iface_var);
+               parent_var_decl.initializer = new CCodeConstant ("NULL");
+               parent_decl.add_declarator (parent_var_decl);
+               parent_decl.modifiers = CCodeModifiers.STATIC;
+               source_type_member_declaration.append (parent_decl);
+               ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_interface_peek_parent"));
+               ccall.add_argument (new CCodeIdentifier ("iface"));
+               var parent_assignment = new CCodeAssignment (new CCodeIdentifier (parent_iface_var), ccall);
+               init_block.add_statement (new CCodeExpressionStatement (parent_assignment));
+
+               var methods = cl.get_methods ();
+               foreach (Method m in methods) {
+                       if (m.base_interface_method == null) {
+                               continue;
+                       }
+
+                       var base_type = m.base_interface_method.symbol.parent_symbol.node;
+                       if (base_type != iface) {
+                               continue;
+                       }
+                       
+                       var ciface = new CCodeIdentifier ("iface");
+                       init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ciface, m.name), new CCodeIdentifier (m.get_real_cname ()))));
+               }
+               
+               source_type_member_definition.append (iface_init);
+       }
+       
+       private void add_instance_init_function (Class! cl) {
+               var instance_init = new CCodeFunction ("%s_init".printf (cl.get_lower_case_cname (null)), "void");
+               instance_init.add_parameter (new CCodeFormalParameter ("self", "%s *".printf (cl.get_cname ())));
+               instance_init.modifiers = CCodeModifiers.STATIC;
+               
+               var init_block = new CCodeBlock ();
+               instance_init.block = init_block;
+               
+               if (cl.has_private_fields) {
+                       var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (cl.get_upper_case_cname (null))));
+                       ccall.add_argument (new CCodeIdentifier ("self"));
+                       init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), ccall)));
+               }
+               
+               init_block.add_statement (instance_init_fragment);
+               
+               var init_sym = cl.symbol.lookup ("init");
+               if (init_sym != null) {
+                       var init_fun = (Method) init_sym.node;
+                       init_block.add_statement (init_fun.body.ccodenode);
+               }
+               
+               source_type_member_definition.append (instance_init);
+       }
+       
+       private void add_dispose_function (Class! cl) {
+               function = new CCodeFunction ("%s_dispose".printf (cl.get_lower_case_cname (null)), "void");
+               function.modifiers = CCodeModifiers.STATIC;
+               
+               function.add_parameter (new CCodeFormalParameter ("obj", "GObject *"));
+               
+               source_type_member_declaration.append (function.copy ());
+
+
+               var cblock = new CCodeBlock ();
+
+               var ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null)));
+               ccall.add_argument (new CCodeIdentifier ("obj"));
+               
+               var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
+               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
+               
+               cblock.add_statement (cdecl);
+               
+               cblock.add_statement (instance_dispose_fragment);
+
+               cdecl = new CCodeDeclaration ("%sClass *".printf (cl.get_cname ()));
+               cdecl.add_declarator (new CCodeVariableDeclarator ("klass"));
+               cblock.add_statement (cdecl);
+
+               cdecl = new CCodeDeclaration ("GObjectClass *");
+               cdecl.add_declarator (new CCodeVariableDeclarator ("parent_class"));
+               cblock.add_statement (cdecl);
+
+
+               ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek"));
+               ccall.add_argument (new CCodeIdentifier (cl.get_upper_case_cname ("TYPE_")));
+               var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (cl.get_upper_case_cname (null))));
+               ccast.add_argument (ccall);
+               cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("klass"), ccast)));
+
+               ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek_parent"));
+               ccall.add_argument (new CCodeIdentifier ("klass"));
+               ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
+               ccast.add_argument (ccall);
+               cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_class"), ccast)));
+
+               
+               ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (new CCodeIdentifier ("parent_class"), "dispose"));
+               ccall.add_argument (new CCodeIdentifier ("obj"));
+               cblock.add_statement (new CCodeExpressionStatement (ccall));
+
+
+               function.block = cblock;
+
+               source_type_member_definition.append (function);
+       }
+       
+       private ref CCodeIdentifier! get_value_setter_function (TypeReference! type_reference) {
+               if (type_reference.data_type is Class || type_reference.data_type is Interface) {
+                       return new CCodeIdentifier ("g_value_set_object");
+               } else if (type_reference.data_type == string_type.data_type) {
+                       return new CCodeIdentifier ("g_value_set_string");
+               } else if (type_reference.data_type == int_type.data_type
+                          || type_reference.data_type is Enum) {
+                       return new CCodeIdentifier ("g_value_set_int");
+               } else if (type_reference.data_type == uint_type.data_type) {
+                       return new CCodeIdentifier ("g_value_set_uint");
+               } else if (type_reference.data_type == long_type.data_type) {
+                       return new CCodeIdentifier ("g_value_set_long");
+               } else if (type_reference.data_type == ulong_type.data_type) {
+                       return new CCodeIdentifier ("g_value_set_ulong");
+               } else if (type_reference.data_type == bool_type.data_type) {
+                       return new CCodeIdentifier ("g_value_set_boolean");
+               } else if (type_reference.data_type == float_type.data_type) {
+                       return new CCodeIdentifier ("g_value_set_float");
+               } else if (type_reference.data_type == double_type.data_type) {
+                       return new CCodeIdentifier ("g_value_set_double");
+               } else {
+                       return new CCodeIdentifier ("g_value_set_pointer");
+               }
+       }
+       
+       private void add_get_property_function (Class! cl) {
+               var get_prop = new CCodeFunction ("%s_get_property".printf (cl.get_lower_case_cname (null)), "void");
+               get_prop.modifiers = CCodeModifiers.STATIC;
+               get_prop.add_parameter (new CCodeFormalParameter ("object", "GObject *"));
+               get_prop.add_parameter (new CCodeFormalParameter ("property_id", "guint"));
+               get_prop.add_parameter (new CCodeFormalParameter ("value", "GValue *"));
+               get_prop.add_parameter (new CCodeFormalParameter ("pspec", "GParamSpec *"));
+               
+               var block = new CCodeBlock ();
+               
+               var ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null)));
+               ccall.add_argument (new CCodeIdentifier ("object"));
+               var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
+               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
+               block.add_statement (cdecl);
+               
+               var cswitch = new CCodeSwitchStatement (new CCodeIdentifier ("property_id"));
+               var props = cl.get_properties ();
+               foreach (Property prop in props) {
+                       if (prop.get_accessor == null || prop.is_abstract) {
+                               continue;
+                       }
+
+                       bool is_virtual = prop.base_property != null || prop.base_interface_property != null;
+
+                       string prefix = cl.get_lower_case_cname (null);
+                       if (is_virtual) {
+                               prefix += "_real";
+                       }
+
+                       var ccase = new CCodeCaseStatement (new CCodeIdentifier (prop.get_upper_case_cname ()));
+                       var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_get_%s".printf (prefix, prop.name)));
+                       ccall.add_argument (new CCodeIdentifier ("self"));
+                       var csetcall = new CCodeFunctionCall ();
+                       csetcall.call = get_value_setter_function (prop.type_reference);
+                       csetcall.add_argument (new CCodeIdentifier ("value"));
+                       csetcall.add_argument (ccall);
+                       ccase.add_statement (new CCodeExpressionStatement (csetcall));
+                       ccase.add_statement (new CCodeBreakStatement ());
+                       cswitch.add_case (ccase);
+               }
+               block.add_statement (cswitch);
+
+               get_prop.block = block;
+               
+               source_type_member_definition.append (get_prop);
+       }
+       
+       private void add_set_property_function (Class! cl) {
+               var set_prop = new CCodeFunction ("%s_set_property".printf (cl.get_lower_case_cname (null)), "void");
+               set_prop.modifiers = CCodeModifiers.STATIC;
+               set_prop.add_parameter (new CCodeFormalParameter ("object", "GObject *"));
+               set_prop.add_parameter (new CCodeFormalParameter ("property_id", "guint"));
+               set_prop.add_parameter (new CCodeFormalParameter ("value", "const GValue *"));
+               set_prop.add_parameter (new CCodeFormalParameter ("pspec", "GParamSpec *"));
+               
+               var block = new CCodeBlock ();
+               
+               var ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null)));
+               ccall.add_argument (new CCodeIdentifier ("object"));
+               var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
+               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
+               block.add_statement (cdecl);
+               
+               var cswitch = new CCodeSwitchStatement (new CCodeIdentifier ("property_id"));
+               var props = cl.get_properties ();
+               foreach (Property prop in props) {
+                       if (prop.set_accessor == null || prop.is_abstract) {
+                               continue;
+                       }
+
+                       bool is_virtual = prop.base_property != null || prop.base_interface_property != null;
+
+                       string prefix = cl.get_lower_case_cname (null);
+                       if (is_virtual) {
+                               prefix += "_real";
+                       }
+
+                       var ccase = new CCodeCaseStatement (new CCodeIdentifier (prop.get_upper_case_cname ()));
+                       var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_set_%s".printf (prefix, prop.name)));
+                       ccall.add_argument (new CCodeIdentifier ("self"));
+                       var cgetcall = new CCodeFunctionCall ();
+                       if (prop.type_reference.data_type is Class || prop.type_reference.data_type is Interface) {
+                               cgetcall.call = new CCodeIdentifier ("g_value_get_object");
+                       } else if (prop.type_reference.type_name == "string") {
+                               cgetcall.call = new CCodeIdentifier ("g_value_get_string");
+                       } else if (prop.type_reference.type_name == "int" || prop.type_reference.data_type is Enum) {
+                               cgetcall.call = new CCodeIdentifier ("g_value_get_int");
+                       } else if (prop.type_reference.type_name == "uint") {
+                               cgetcall.call = new CCodeIdentifier ("g_value_get_uint");
+                       } else if (prop.type_reference.type_name == "long") {
+                               cgetcall.call = new CCodeIdentifier ("g_value_get_long");
+                       } else if (prop.type_reference.type_name == "ulong") {
+                               cgetcall.call = new CCodeIdentifier ("g_value_get_ulong");
+                       } else if (prop.type_reference.type_name == "bool") {
+                               cgetcall.call = new CCodeIdentifier ("g_value_get_boolean");
+                       } else if (prop.type_reference.type_name == "float") {
+                               cgetcall.call = new CCodeIdentifier ("g_value_get_float");
+                       } else if (prop.type_reference.type_name == "double") {
+                               cgetcall.call = new CCodeIdentifier ("g_value_get_double");
+                       } else {
+                               cgetcall.call = new CCodeIdentifier ("g_value_get_pointer");
+                       }
+                       cgetcall.add_argument (new CCodeIdentifier ("value"));
+                       ccall.add_argument (cgetcall);
+                       ccase.add_statement (new CCodeExpressionStatement (ccall));
+                       ccase.add_statement (new CCodeBreakStatement ());
+                       cswitch.add_case (ccase);
+               }
+               block.add_statement (cswitch);
+
+               /* destroy func properties for generic types */
+               foreach (TypeParameter type_param in cl.get_type_parameters ()) {
+                       string func_name = "%s_destroy_func".printf (type_param.name.down ());
+                       string enum_value = "%s_%s".printf (cl.get_lower_case_cname (null), func_name).up ();
+
+                       var ccase = new CCodeCaseStatement (new CCodeIdentifier (enum_value));
+                       var cfield = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name);
+                       var cgetcall = new CCodeFunctionCall (new CCodeIdentifier ("g_value_get_pointer"));
+                       cgetcall.add_argument (new CCodeIdentifier ("value"));
+                       ccase.add_statement (new CCodeExpressionStatement (new CCodeAssignment (cfield, cgetcall)));
+                       ccase.add_statement (new CCodeBreakStatement ());
+                       cswitch.add_case (ccase);
+               }
+
+               set_prop.block = block;
+               
+               source_type_member_definition.append (set_prop);
+       }
+}
diff --git a/gobject/valacodegeneratorinterface.vala b/gobject/valacodegeneratorinterface.vala
new file mode 100644 (file)
index 0000000..8252993
--- /dev/null
@@ -0,0 +1,217 @@
+/* valacodegeneratorinterface.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>
+ */
+
+using GLib;
+
+public class Vala.CodeGenerator {
+       public override void visit_begin_interface (Interface! iface) {
+               current_symbol = iface.symbol;
+               current_type_symbol = iface.symbol;
+
+               if (iface.is_static) {
+                       return;
+               }
+
+               type_struct = new CCodeStruct ("_%s".printf (iface.get_type_cname ()));
+               
+               header_type_declaration.append (new CCodeNewline ());
+               var macro = "(%s_get_type ())".printf (iface.get_lower_case_cname (null));
+               header_type_declaration.append (new CCodeMacroReplacement (iface.get_upper_case_cname ("TYPE_"), macro));
+
+               macro = "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (iface.get_upper_case_cname ("TYPE_"), iface.get_cname ());
+               header_type_declaration.append (new CCodeMacroReplacement ("%s(obj)".printf (iface.get_upper_case_cname (null)), macro));
+
+               macro = "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (iface.get_upper_case_cname ("TYPE_"));
+               header_type_declaration.append (new CCodeMacroReplacement ("%s(obj)".printf (iface.get_upper_case_cname ("IS_")), macro));
+
+               macro = "(G_TYPE_INSTANCE_GET_INTERFACE ((obj), %s, %s))".printf (iface.get_upper_case_cname ("TYPE_"), iface.get_type_cname ());
+               header_type_declaration.append (new CCodeMacroReplacement ("%s_GET_INTERFACE(obj)".printf (iface.get_upper_case_cname (null)), macro));
+               header_type_declaration.append (new CCodeNewline ());
+
+
+               if (iface.source_reference.file.cycle == null) {
+                       header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (iface.get_cname ()), new CCodeVariableDeclarator (iface.get_cname ())));
+                       header_type_declaration.append (new CCodeTypeDefinition ("struct %s".printf (type_struct.name), new CCodeVariableDeclarator (iface.get_type_cname ())));
+               }
+               
+               type_struct.add_field ("GTypeInterface", "parent");
+
+               if (iface.source_reference.comment != null) {
+                       header_type_definition.append (new CCodeComment (iface.source_reference.comment));
+               }
+               header_type_definition.append (type_struct);
+       }
+
+       public override void visit_end_interface (Interface! iface) {
+               if (!iface.is_static) {
+                       add_interface_base_init_function (iface);
+
+                       var type_fun = new InterfaceRegisterFunction (iface);
+                       type_fun.init_from_type ();
+                       header_type_member_declaration.append (type_fun.get_declaration ());
+                       source_type_member_definition.append (type_fun.get_definition ());
+               }
+
+               current_type_symbol = null;
+       }
+       
+       private ref CCodeFunctionCall! get_param_spec (Property! prop) {
+               var cspec = new CCodeFunctionCall ();
+               cspec.add_argument (prop.get_canonical_cconstant ());
+               cspec.add_argument (new CCodeConstant ("\"foo\""));
+               cspec.add_argument (new CCodeConstant ("\"bar\""));
+               if (prop.type_reference.data_type is Class || prop.type_reference.data_type is Interface) {
+                       cspec.call = new CCodeIdentifier ("g_param_spec_object");
+                       cspec.add_argument (new CCodeIdentifier (prop.type_reference.data_type.get_upper_case_cname ("TYPE_")));
+               } else if (prop.type_reference.data_type == string_type.data_type) {
+                       cspec.call = new CCodeIdentifier ("g_param_spec_string");
+                       cspec.add_argument (new CCodeConstant ("NULL"));
+               } else if (prop.type_reference.data_type == int_type.data_type
+                          || prop.type_reference.data_type is Enum) {
+                       cspec.call = new CCodeIdentifier ("g_param_spec_int");
+                       cspec.add_argument (new CCodeConstant ("G_MININT"));
+                       cspec.add_argument (new CCodeConstant ("G_MAXINT"));
+                       cspec.add_argument (new CCodeConstant ("0"));
+               } else if (prop.type_reference.data_type == uint_type.data_type) {
+                       cspec.call = new CCodeIdentifier ("g_param_spec_uint");
+                       cspec.add_argument (new CCodeConstant ("0"));
+                       cspec.add_argument (new CCodeConstant ("G_MAXUINT"));
+                       cspec.add_argument (new CCodeConstant ("0U"));
+               } else if (prop.type_reference.data_type == long_type.data_type) {
+                       cspec.call = new CCodeIdentifier ("g_param_spec_long");
+                       cspec.add_argument (new CCodeConstant ("G_MINLONG"));
+                       cspec.add_argument (new CCodeConstant ("G_MAXLONG"));
+                       cspec.add_argument (new CCodeConstant ("0L"));
+               } else if (prop.type_reference.data_type == ulong_type.data_type) {
+                       cspec.call = new CCodeIdentifier ("g_param_spec_ulong");
+                       cspec.add_argument (new CCodeConstant ("0"));
+                       cspec.add_argument (new CCodeConstant ("G_MAXULONG"));
+                       cspec.add_argument (new CCodeConstant ("0UL"));
+               } else if (prop.type_reference.data_type == bool_type.data_type) {
+                       cspec.call = new CCodeIdentifier ("g_param_spec_boolean");
+                       cspec.add_argument (new CCodeConstant ("FALSE"));
+               } else if (prop.type_reference.data_type == float_type.data_type) {
+                       cspec.call = new CCodeIdentifier ("g_param_spec_float");
+                       cspec.add_argument (new CCodeConstant ("-G_MAXFLOAT"));
+                       cspec.add_argument (new CCodeConstant ("G_MAXFLOAT"));
+                       cspec.add_argument (new CCodeConstant ("0.0F"));
+               } else if (prop.type_reference.data_type == double_type.data_type) {
+                       cspec.call = new CCodeIdentifier ("g_param_spec_double");
+                       cspec.add_argument (new CCodeConstant ("-G_MAXDOUBLE"));
+                       cspec.add_argument (new CCodeConstant ("G_MAXDOUBLE"));
+                       cspec.add_argument (new CCodeConstant ("0.0"));
+               } else {
+                       cspec.call = new CCodeIdentifier ("g_param_spec_pointer");
+               }
+               
+               var pflags = "G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB";
+               if (prop.get_accessor != null) {
+                       pflags = "%s%s".printf (pflags, " | G_PARAM_READABLE");
+               }
+               if (prop.set_accessor != null) {
+                       pflags = "%s%s".printf (pflags, " | G_PARAM_WRITABLE");
+                       if (prop.set_accessor.construction) {
+                               if (prop.set_accessor.writable) {
+                                       pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT");
+                               } else {
+                                       pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT_ONLY");
+                               }
+                       }
+               }
+               cspec.add_argument (new CCodeConstant (pflags));
+
+               return cspec;
+       }
+
+       private ref CCodeFunctionCall! get_signal_creation (Signal! sig, DataType! type) {      
+               var csignew = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_new"));
+               csignew.add_argument (new CCodeConstant ("\"%s\"".printf (sig.name)));
+               csignew.add_argument (new CCodeIdentifier (type.get_upper_case_cname ("TYPE_")));
+               csignew.add_argument (new CCodeConstant ("G_SIGNAL_RUN_LAST"));
+               csignew.add_argument (new CCodeConstant ("0"));
+               csignew.add_argument (new CCodeConstant ("NULL"));
+               csignew.add_argument (new CCodeConstant ("NULL"));
+
+               string marshaller = get_signal_marshaller_function (sig);
+
+               var marshal_arg = new CCodeIdentifier (marshaller);
+               csignew.add_argument (marshal_arg);
+
+               var params = sig.get_parameters ();
+               var params_len = params.length ();
+               if (sig.return_type.type_parameter != null) {
+                       csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
+               } else if (sig.return_type.data_type == null) {
+                       csignew.add_argument (new CCodeConstant ("G_TYPE_NONE"));
+               } else {
+                       csignew.add_argument (new CCodeConstant (sig.return_type.data_type.get_type_id ()));
+               }
+               csignew.add_argument (new CCodeConstant ("%d".printf (params_len)));
+               foreach (FormalParameter param in params) {
+                       if (param.type_reference.type_parameter != null) {
+                               csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
+                       } else {
+                               csignew.add_argument (new CCodeConstant (param.type_reference.data_type.get_type_id ()));
+                       }
+               }
+
+               marshal_arg.name = marshaller;
+
+               return csignew;
+       }
+
+       private void add_interface_base_init_function (Interface! iface) {
+               var base_init = new CCodeFunction ("%s_base_init".printf (iface.get_lower_case_cname (null)), "void");
+               base_init.add_parameter (new CCodeFormalParameter ("iface", "%sIface *".printf (iface.get_cname ())));
+               base_init.modifiers = CCodeModifiers.STATIC;
+               
+               var init_block = new CCodeBlock ();
+               
+               /* make sure not to run the initialization code twice */
+               base_init.block = new CCodeBlock ();
+               var decl = new CCodeDeclaration (bool_type.get_cname ());
+               decl.modifiers |= CCodeModifiers.STATIC;
+               decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("initialized", new CCodeConstant ("FALSE")));
+               base_init.block.add_statement (decl);
+               var cif = new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("initialized")), init_block);
+               base_init.block.add_statement (cif);
+               init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("initialized"), new CCodeConstant ("TRUE"))));
+               
+               /* create properties */
+               var props = iface.get_properties ();
+               foreach (Property prop in props) {
+                       var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_interface_install_property"));
+                       cinst.add_argument (new CCodeIdentifier ("iface"));
+                       cinst.add_argument (get_param_spec (prop));
+
+                       init_block.add_statement (new CCodeExpressionStatement (cinst));
+               }
+               
+               /* create signals */
+               foreach (Signal sig in iface.get_signals ()) {
+                       init_block.add_statement (new CCodeExpressionStatement (get_signal_creation (sig, iface)));
+               }
+               
+               source_type_member_definition.append (base_init);
+       }
+}
diff --git a/gobject/valacodegeneratorinvocationexpression.vala b/gobject/valacodegeneratorinvocationexpression.vala
new file mode 100644 (file)
index 0000000..7e9f801
--- /dev/null
@@ -0,0 +1,246 @@
+/* valacodegeneratorinvocationexpression.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>
+ */
+
+using GLib;
+
+public class Vala.CodeGenerator {
+       public override void visit_end_invocation_expression (InvocationExpression! expr) {
+               var ccall = new CCodeFunctionCall ((CCodeExpression) expr.call.ccodenode);
+               
+               Method m = null;
+               List<weak FormalParameter> params;
+               
+               if (!(expr.call is MemberAccess)) {
+                       expr.error = true;
+                       Report.error (expr.source_reference, "unsupported method invocation");
+                       return;
+               }
+               
+               var ma = (MemberAccess) expr.call;
+               
+               if (expr.call.symbol_reference.node is Invokable) {
+                       var i = (Invokable) expr.call.symbol_reference.node;
+                       params = i.get_parameters ();
+                       
+                       if (i is Method) {
+                               m = (Method) i;
+                       } else if (i is Signal) {
+                               ccall = (CCodeFunctionCall) expr.call.ccodenode;
+                       }
+               }
+               
+               if (m is ArrayResizeMethod) {
+                       var array = (Array) m.symbol.parent_symbol.node;
+                       ccall.add_argument (new CCodeIdentifier (array.get_cname ()));
+               }
+               
+               /* explicitly use strong reference as ccall gets unrefed
+                * at end of inner block
+                */
+               ref CCodeExpression instance;
+               if (m != null && m.instance) {
+                       var base_method = m;
+                       if (m.base_interface_method != null) {
+                               base_method = m.base_interface_method;
+                       } else if (m.base_method != null) {
+                               base_method = m.base_method;
+                       }
+
+                       var req_cast = false;
+                       if (ma.inner == null) {
+                               instance = new CCodeIdentifier ("self");
+                               /* require casts for overriden and inherited methods */
+                               req_cast = m.overrides || m.base_interface_method != null || (m.symbol.parent_symbol != current_type_symbol);
+                       } else {
+                               instance = (CCodeExpression) ma.inner.ccodenode;
+                               /* reqiure casts if the type of the used instance is
+                                * different than the type which declared the method */
+                               req_cast = base_method.symbol.parent_symbol.node != ma.inner.static_type.data_type;
+                       }
+                       
+                       if (m.instance_by_reference && (ma.inner != null || m.symbol.parent_symbol != current_type_symbol)) {
+                               instance = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance);
+                       }
+                       
+                       if (req_cast && ((DataType) m.symbol.parent_symbol.node).is_reference_type ()) {
+                               // FIXME: use C cast if debugging disabled
+                               var ccall = new CCodeFunctionCall (new CCodeIdentifier (((DataType) base_method.symbol.parent_symbol.node).get_upper_case_cname (null)));
+                               ccall.add_argument (instance);
+                               instance = ccall;
+                       }
+                       
+                       if (!m.instance_last) {
+                               ccall.add_argument (instance);
+                       }
+               }
+               
+               bool ellipsis = false;
+               
+               var i = 1;
+               weak List<weak FormalParameter> params_it = params;
+               foreach (Expression arg in expr.get_argument_list ()) {
+                       /* explicitly use strong reference as ccall gets
+                        * unrefed at end of inner block
+                        */
+                       ref CCodeExpression cexpr = (CCodeExpression) arg.ccodenode;
+                       if (params_it != null) {
+                               var param = (FormalParameter) params_it.data;
+                               ellipsis = param.ellipsis;
+                               if (!ellipsis) {
+                                       if (param.type_reference.data_type != null
+                                           && param.type_reference.data_type.is_reference_type ()
+                                           && arg.static_type.data_type != null) {
+                                               if (!param.no_array_length && param.type_reference.data_type is Array) {
+                                                       var arr = (Array) param.type_reference.data_type;
+                                                       for (int dim = 1; dim <= arr.rank; dim++) {
+                                                               ccall.add_argument (get_array_length_cexpression (arg, dim));
+                                                       }
+                                               }
+                                               if (param.type_reference.data_type != arg.static_type.data_type) {
+                                                       // FIXME: use C cast if debugging disabled
+                                                       var ccall = new CCodeFunctionCall (new CCodeIdentifier (param.type_reference.data_type.get_upper_case_cname (null)));
+                                                       ccall.add_argument (cexpr);
+                                                       cexpr = ccall;
+                                               }
+                                       } else if (param.type_reference.data_type is Callback) {
+                                               cexpr = new CCodeCastExpression (cexpr, param.type_reference.data_type.get_cname ());
+                                       } else if (param.type_reference.data_type == null
+                                                  && arg.static_type.data_type is Struct) {
+                                               /* convert integer to pointer if this is a generic method parameter */
+                                               var st = (Struct) arg.static_type.data_type;
+                                               if (st == bool_type.data_type || st.is_integer_type ()) {
+                                                       var cconv = new CCodeFunctionCall (new CCodeIdentifier ("GINT_TO_POINTER"));
+                                                       cconv.add_argument (cexpr);
+                                                       cexpr = cconv;
+                                               }
+                                       }
+                               }
+                       }
+                                       
+                       ccall.add_argument (cexpr);
+                       i++;
+                       
+                       if (params_it != null) {
+                               params_it = params_it.next;
+                       }
+               }
+               while (params_it != null) {
+                       var param = (FormalParameter) params_it.data;
+                       
+                       if (param.ellipsis) {
+                               ellipsis = true;
+                               break;
+                       }
+                       
+                       if (param.default_expression == null) {
+                               Report.error (expr.source_reference, "no default expression for argument %d".printf (i));
+                               return;
+                       }
+                       
+                       /* evaluate default expression here as the code
+                        * generator might not have visited the formal
+                        * parameter yet */
+                       param.default_expression.accept (this);
+               
+                       if (!param.no_array_length && param.type_reference != null &&
+                           param.type_reference.data_type is Array) {
+                               var arr = (Array) param.type_reference.data_type;
+                               for (int dim = 1; dim <= arr.rank; dim++) {
+                                       ccall.add_argument (get_array_length_cexpression (param.default_expression, dim));
+                               }
+                       }
+
+                       ccall.add_argument ((CCodeExpression) param.default_expression.ccodenode);
+                       i++;
+               
+                       params_it = params_it.next;
+               }
+               
+               if (m != null && m.instance && m.instance_last) {
+                       ccall.add_argument (instance);
+               } else if (ellipsis) {
+                       /* ensure variable argument list ends with NULL
+                        * except when using printf-style arguments */
+                       if (m == null || !m.printf_format) {
+                               ccall.add_argument (new CCodeConstant ("NULL"));
+                       }
+               }
+               
+               if (m != null && m.instance && m.returns_modified_pointer) {
+                       expr.ccodenode = new CCodeAssignment (instance, ccall);
+               } else {
+                       /* cast pointer to actual type if this is a generic method return value */
+                       if (m != null && m.return_type.type_parameter != null && expr.static_type.data_type != null) {
+                               if (expr.static_type.data_type is Struct) {
+                                       var st = (Struct) expr.static_type.data_type;
+                                       if (st == uint_type.data_type) {
+                                               var cconv = new CCodeFunctionCall (new CCodeIdentifier ("GPOINTER_TO_UINT"));
+                                               cconv.add_argument (ccall);
+                                               ccall = cconv;
+                                       } else if (st == bool_type.data_type || st.is_integer_type ()) {
+                                               var cconv = new CCodeFunctionCall (new CCodeIdentifier ("GPOINTER_TO_INT"));
+                                               cconv.add_argument (ccall);
+                                               ccall = cconv;
+                                       }
+                               }
+                       }
+
+                       expr.ccodenode = ccall;
+               
+                       visit_expression (expr);
+               }
+               
+               if (m is ArrayResizeMethod) {
+                       // FIXME: size expression must not be evaluated twice at runtime (potential side effects)
+                       var new_size = (CCodeExpression) ((CodeNode) expr.get_argument_list ().data).ccodenode;
+
+                       var temp_decl = get_temp_variable_declarator (int_type);
+                       var temp_ref = new CCodeIdentifier (temp_decl.name);
+
+                       temp_vars.prepend (temp_decl);
+
+                       /* memset needs string.h */
+                       string_h_needed = true;
+
+                       var clen = get_array_length_cexpression (ma.inner, 1);
+                       var celems = (CCodeExpression)ma.inner.ccodenode;
+                       var csizeof = new CCodeIdentifier ("sizeof (%s)".printf (ma.inner.static_type.data_type.get_cname ()));
+                       var cdelta = new CCodeParenthesizedExpression (new CCodeBinaryExpression (CCodeBinaryOperator.MINUS, temp_ref, clen));
+                       var ccheck = new CCodeBinaryExpression (CCodeBinaryOperator.GREATER_THAN, temp_ref, clen);
+
+                       var czero = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
+                       czero.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, celems, clen));
+                       czero.add_argument (new CCodeConstant ("0"));
+                       czero.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, csizeof, cdelta));
+
+                       var ccomma = new CCodeCommaExpression ();
+                       ccomma.append_expression (new CCodeAssignment (temp_ref, new_size));
+                       ccomma.append_expression ((CCodeExpression) expr.ccodenode);
+                       ccomma.append_expression (new CCodeConditionalExpression (ccheck, czero, new CCodeConstant ("NULL")));
+                       ccomma.append_expression (new CCodeAssignment (get_array_length_cexpression (ma.inner, 1), temp_ref));
+
+                       expr.ccodenode = ccomma;
+               }
+       }
+}
+
diff --git a/gobject/valacodegeneratormemberaccess.vala b/gobject/valacodegeneratormemberaccess.vala
new file mode 100644 (file)
index 0000000..05b9a0f
--- /dev/null
@@ -0,0 +1,221 @@
+/* valacodegeneratormemberaccess.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>
+ */
+
+using GLib;
+
+public class Vala.CodeGenerator {
+       private void process_cmember (MemberAccess! expr, CCodeExpression pub_inst, DataType base_type) {
+               if (expr.symbol_reference.node is Method) {
+                       var m = (Method) expr.symbol_reference.node;
+                       
+                       if (expr.inner is BaseAccess) {
+                               if (m.base_interface_method != null) {
+                                       var base_iface = (Interface) m.base_interface_method.symbol.parent_symbol.node;
+                                       string parent_iface_var = "%s_%s_parent_iface".printf (current_class.get_lower_case_cname (null), base_iface.get_lower_case_cname (null));
+
+                                       expr.ccodenode = new CCodeMemberAccess.pointer (new CCodeIdentifier (parent_iface_var), m.name);
+                                       return;
+                               } else if (m.base_method != null) {
+                                       var base_class = (Class) m.base_method.symbol.parent_symbol.node;
+                                       var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (base_class.get_upper_case_cname (null))));
+                                       vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (current_class.get_lower_case_cname (null))));
+                                       
+                                       expr.ccodenode = new CCodeMemberAccess.pointer (vcast, m.name);
+                                       return;
+                               }
+                       }
+                       
+                       if (m.base_interface_method != null) {
+                               expr.ccodenode = new CCodeIdentifier (m.base_interface_method.get_cname ());
+                       } else if (m.base_method != null) {
+                               expr.ccodenode = new CCodeIdentifier (m.base_method.get_cname ());
+                       } else {
+                               expr.ccodenode = new CCodeIdentifier (m.get_cname ());
+                       }
+               } else if (expr.symbol_reference.node is ArrayLengthField) {
+                       expr.ccodenode = get_array_length_cexpression (expr.inner, 1);
+               } else if (expr.symbol_reference.node is Field) {
+                       var f = (Field) expr.symbol_reference.node;
+                       if (f.instance) {
+                               ref CCodeExpression typed_inst;
+                               if (f.symbol.parent_symbol.node != base_type) {
+                                       // FIXME: use C cast if debugging disabled
+                                       typed_inst = new CCodeFunctionCall (new CCodeIdentifier (((DataType) f.symbol.parent_symbol.node).get_upper_case_cname (null)));
+                                       ((CCodeFunctionCall) typed_inst).add_argument (pub_inst);
+                               } else {
+                                       typed_inst = pub_inst;
+                               }
+                               ref CCodeExpression inst;
+                               if (f.access == MemberAccessibility.PRIVATE) {
+                                       inst = new CCodeMemberAccess.pointer (typed_inst, "priv");
+                               } else {
+                                       inst = typed_inst;
+                               }
+                               if (((DataType) f.symbol.parent_symbol.node).is_reference_type ()) {
+                                       expr.ccodenode = new CCodeMemberAccess.pointer (inst, f.get_cname ());
+                               } else {
+                                       expr.ccodenode = new CCodeMemberAccess (inst, f.get_cname ());
+                               }
+                       } else {
+                               expr.ccodenode = new CCodeIdentifier (f.get_cname ());
+                       }
+               } else if (expr.symbol_reference.node is Constant) {
+                       var c = (Constant) expr.symbol_reference.node;
+                       expr.ccodenode = new CCodeIdentifier (c.get_cname ());
+               } else if (expr.symbol_reference.node is Property) {
+                       var prop = (Property) expr.symbol_reference.node;
+
+                       if (!prop.no_accessor_method) {
+                               var base_property = prop;
+                               if (prop.base_property != null) {
+                                       base_property = prop.base_property;
+                               } else if (prop.base_interface_property != null) {
+                                       base_property = prop.base_interface_property;
+                               }
+                               var base_property_type = (DataType) base_property.symbol.parent_symbol.node;
+                               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_get_%s".printf (base_property_type.get_lower_case_cname (null), base_property.name)));
+                               
+                               /* explicitly use strong reference as ccast
+                                * gets unrefed at the end of the inner block
+                                */
+                               ref CCodeExpression typed_pub_inst = pub_inst;
+
+                               /* cast if necessary */
+                               if (base_property_type != base_type) {
+                                       // FIXME: use C cast if debugging disabled
+                                       var ccast = new CCodeFunctionCall (new CCodeIdentifier (base_property_type.get_upper_case_cname (null)));
+                                       ccast.add_argument (pub_inst);
+                                       typed_pub_inst = ccast;
+                               }
+
+                               ccall.add_argument (typed_pub_inst);
+                               expr.ccodenode = ccall;
+                       } else {
+                               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get"));
+                       
+                               var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
+                               ccast.add_argument (pub_inst);
+                               ccall.add_argument (ccast);
+                               
+                               // property name is second argument of g_object_get
+                               ccall.add_argument (prop.get_canonical_cconstant ());
+                               
+                               
+                               // we need a temporary variable to save the property value
+                               var temp_decl = get_temp_variable_declarator (expr.static_type);
+                               temp_vars.prepend (temp_decl);
+
+                               var ctemp = new CCodeIdentifier (temp_decl.name);
+                               ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
+                               
+                               
+                               ccall.add_argument (new CCodeConstant ("NULL"));
+                               
+                               var ccomma = new CCodeCommaExpression ();
+                               ccomma.append_expression (ccall);
+                               ccomma.append_expression (ctemp);
+                               expr.ccodenode = ccomma;
+                       }
+               } else if (expr.symbol_reference.node is EnumValue) {
+                       var ev = (EnumValue) expr.symbol_reference.node;
+                       expr.ccodenode = new CCodeConstant (ev.get_cname ());
+               } else if (expr.symbol_reference.node is VariableDeclarator) {
+                       var decl = (VariableDeclarator) expr.symbol_reference.node;
+                       expr.ccodenode = new CCodeIdentifier (decl.name);
+               } else if (expr.symbol_reference.node is FormalParameter) {
+                       var p = (FormalParameter) expr.symbol_reference.node;
+                       if (p.name == "this") {
+                               expr.ccodenode = pub_inst;
+                       } else {
+                               if (p.type_reference.is_out || p.type_reference.reference_to_value_type) {
+                                       expr.ccodenode = new CCodeIdentifier ("(*%s)".printf (p.name));
+                               } else {
+                                       expr.ccodenode = new CCodeIdentifier (p.name);
+                               }
+                       }
+               } else if (expr.symbol_reference.node is Signal) {
+                       var sig = (Signal) expr.symbol_reference.node;
+                       var cl = (DataType) sig.symbol.parent_symbol.node;
+                       
+                       if (sig.has_emitter) {
+                               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_%s".printf (cl.get_lower_case_cname (null), sig.name)));
+                               
+                               /* explicitly use strong reference as ccast
+                                * gets unrefed at the end of the inner block
+                                */
+                               ref CCodeExpression typed_pub_inst = pub_inst;
+
+                               /* cast if necessary */
+                               if (cl != base_type) {
+                                       // FIXME: use C cast if debugging disabled
+                                       var ccast = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null)));
+                                       ccast.add_argument (pub_inst);
+                                       typed_pub_inst = ccast;
+                               }
+
+                               ccall.add_argument (typed_pub_inst);
+                               expr.ccodenode = ccall;
+                       } else {
+                               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
+
+                               // FIXME: use C cast if debugging disabled
+                               var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
+                               ccast.add_argument (pub_inst);
+                               ccall.add_argument (ccast);
+
+                               ccall.add_argument (sig.get_canonical_cconstant ());
+                               
+                               expr.ccodenode = ccall;
+                       }
+               }
+       }
+
+       public override void visit_member_access (MemberAccess! expr) {
+               CCodeExpression pub_inst = null;
+               DataType base_type = null;
+       
+               if (expr.inner == null) {
+                       pub_inst = new CCodeIdentifier ("self");
+
+                       if (current_type_symbol != null) {
+                               /* base type is available if this is a type method */
+                               base_type = (DataType) current_type_symbol.node;
+                               
+                               if (!base_type.is_reference_type ()) {
+                                       pub_inst = new CCodeIdentifier ("(*self)");
+                               }
+                       }
+               } else {
+                       pub_inst = (CCodeExpression) expr.inner.ccodenode;
+
+                       if (expr.inner.static_type != null) {
+                               base_type = expr.inner.static_type.data_type;
+                       }
+               }
+
+               process_cmember (expr, pub_inst, base_type);
+
+               visit_expression (expr);
+       }
+}
+
diff --git a/gobject/valacodegeneratormethod.vala b/gobject/valacodegeneratormethod.vala
new file mode 100644 (file)
index 0000000..f366068
--- /dev/null
@@ -0,0 +1,457 @@
+/* valacodegeneratormethod.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>
+ */
+
+using GLib;
+
+public class Vala.CodeGenerator {
+       public override void visit_begin_method (Method! m) {
+               current_symbol = m.symbol;
+               current_return_type = m.return_type;
+       }
+       
+       private ref CCodeStatement create_method_type_check_statement (Method! m, DataType! t, bool non_null, string! var_name) {
+               return create_type_check_statement (m, m.return_type.data_type, t, non_null, var_name);
+       }
+       
+       private ref CCodeStatement create_property_type_check_statement (Property! prop, bool getter, DataType! t, bool non_null, string! var_name) {
+               if (getter) {
+                       return create_type_check_statement (prop, prop.type_reference.data_type, t, non_null, var_name);
+               } else {
+                       return create_type_check_statement (prop, null, t, non_null, var_name);
+               }
+       }
+       
+       private ref CCodeStatement create_type_check_statement (CodeNode! method_node, DataType ret_type, DataType! t, bool non_null, string! var_name) {
+               var ccheck = new CCodeFunctionCall ();
+               
+               if (t is Class || t is Interface) {
+                       var ctype_check = new CCodeFunctionCall (new CCodeIdentifier (t.get_upper_case_cname ("IS_")));
+                       ctype_check.add_argument (new CCodeIdentifier (var_name));
+                       
+                       ref CCodeExpression cexpr = ctype_check;
+                       if (!non_null) {
+                               var cnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier (var_name), new CCodeConstant ("NULL"));
+                       
+                               cexpr = new CCodeBinaryExpression (CCodeBinaryOperator.OR, cnull, ctype_check);
+                       }
+                       ccheck.add_argument (cexpr);
+               } else if (!non_null) {
+                       return null;
+               } else {
+                       var cnonnull = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier (var_name), new CCodeConstant ("NULL"));
+                       ccheck.add_argument (cnonnull);
+               }
+               
+               if (ret_type == null) {
+                       /* void function */
+                       ccheck.call = new CCodeIdentifier ("g_return_if_fail");
+               } else {
+                       ccheck.call = new CCodeIdentifier ("g_return_val_if_fail");
+                       
+                       if (ret_type.is_reference_type () || ret_type is Pointer) {
+                               ccheck.add_argument (new CCodeConstant ("NULL"));
+                       } else if (ret_type.get_default_value () != null) {
+                               ccheck.add_argument (new CCodeConstant (ret_type.get_default_value ()));
+                       } else {
+                               Report.warning (method_node.source_reference, "not supported return type for runtime type checks");
+                               return new CCodeExpressionStatement (new CCodeConstant ("0"));
+                       }
+               }
+               
+               return new CCodeExpressionStatement (ccheck);
+       }
+
+       private DataType find_parent_type (CodeNode node) {
+               var sym = node.symbol;
+               while (sym != null) {
+                       if (sym.node is DataType) {
+                               return (DataType) sym.node;
+                       }
+                       sym = sym.parent_symbol;
+               }
+               return null;
+       }
+       
+       private ref string! get_array_length_cname (string! array_cname, int dim) {
+               return "%s_length%d".printf (array_cname, dim);
+       }
+
+       public override void visit_end_method (Method! m) {
+               current_symbol = current_symbol.parent_symbol;
+               current_return_type = null;
+
+               if (current_type_symbol != null && current_type_symbol.node is Interface) {
+                       var iface = (Interface) current_type_symbol.node;
+                       if (iface.is_static) {
+                               return;
+                       }
+               }
+
+               if (current_symbol.parent_symbol != null &&
+                   current_symbol.parent_symbol.node is Method) {
+                       /* lambda expressions produce nested methods */
+                       var up_method = (Method) current_symbol.parent_symbol.node;
+                       current_return_type = up_method.return_type;
+               }
+
+               function = new CCodeFunction (m.get_real_cname (), m.return_type.get_cname ());
+               CCodeFunctionDeclarator vdeclarator = null;
+               
+               CCodeFormalParameter instance_param = null;
+               
+               if (m.instance) {
+                       var this_type = new TypeReference ();
+                       this_type.data_type = find_parent_type (m);
+                       if (m.base_interface_method != null) {
+                               var base_type = new TypeReference ();
+                               base_type.data_type = (DataType) m.base_interface_method.symbol.parent_symbol.node;
+                               instance_param = new CCodeFormalParameter ("base", base_type.get_cname ());
+                       } else if (m.overrides) {
+                               var base_type = new TypeReference ();
+                               base_type.data_type = (DataType) m.base_method.symbol.parent_symbol.node;
+                               instance_param = new CCodeFormalParameter ("base", base_type.get_cname ());
+                       } else {
+                               if (m.instance_by_reference) {
+                                       instance_param = new CCodeFormalParameter ("*self", this_type.get_cname ());
+                               } else {
+                                       instance_param = new CCodeFormalParameter ("self", this_type.get_cname ());
+                               }
+                       }
+                       if (!m.instance_last) {
+                               function.add_parameter (instance_param);
+                       }
+                       
+                       if (m.is_abstract || m.is_virtual) {
+                               var vdecl = new CCodeDeclaration (m.return_type.get_cname ());
+                               vdeclarator = new CCodeFunctionDeclarator (m.name);
+                               vdecl.add_declarator (vdeclarator);
+                               type_struct.add_declaration (vdecl);
+
+                               vdeclarator.add_parameter (instance_param);
+                       }
+               }
+
+               if (m is CreationMethod && current_class != null) {
+                       // memory management for generic types
+                       foreach (TypeParameter type_param in current_class.get_type_parameters ()) {
+                               var cparam = new CCodeFormalParameter ("%s_destroy_func".printf (type_param.name.down ()), "GDestroyNotify");
+                               function.add_parameter (cparam);
+                       }
+               }
+
+               var params = m.get_parameters ();
+               foreach (FormalParameter param in params) {
+                       if (!param.no_array_length && param.type_reference.data_type is Array) {
+                               var arr = (Array) param.type_reference.data_type;
+                               
+                               var length_ctype = "int";
+                               if (param.type_reference.is_out) {
+                                       length_ctype = "int*";
+                               }
+                               
+                               for (int dim = 1; dim <= arr.rank; dim++) {
+                                       var cparam = new CCodeFormalParameter (get_array_length_cname (param.name, dim), length_ctype);
+                                       function.add_parameter (cparam);
+                                       if (vdeclarator != null) {
+                                               vdeclarator.add_parameter (cparam);
+                                       }
+                               }
+                       }
+               
+                       function.add_parameter ((CCodeFormalParameter) param.ccodenode);
+                       if (vdeclarator != null) {
+                               vdeclarator.add_parameter ((CCodeFormalParameter) param.ccodenode);
+                       }
+               }
+               
+               if (m.instance && m.instance_last) {
+                       function.add_parameter (instance_param);
+               }
+
+               /* real function declaration and definition not needed
+                * for abstract methods */
+               if (!m.is_abstract) {
+                       if (m.access != MemberAccessibility.PRIVATE && m.base_method == null && m.base_interface_method == null) {
+                               /* public methods need function declaration in
+                                * header file except virtual/overridden methods */
+                               header_type_member_declaration.append (function.copy ());
+                       } else {
+                               /* declare all other functions in source file to
+                                * avoid dependency on order within source file */
+                               function.modifiers |= CCodeModifiers.STATIC;
+                               source_type_member_declaration.append (function.copy ());
+                       }
+                       
+                       /* Methods imported from a plain C file don't
+                        * have a body, e.g. Vala.Parser.parse_file () */
+                       if (m.body != null) {
+                               function.block = (CCodeBlock) m.body.ccodenode;
+
+                               var cinit = new CCodeFragment ();
+                               function.block.prepend_statement (cinit);
+
+                               if (m.symbol.parent_symbol.node is Class) {
+                                       var cl = (Class) m.symbol.parent_symbol.node;
+                                       if (m.overrides || m.base_interface_method != null) {
+                                               var ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null)));
+                                               ccall.add_argument (new CCodeIdentifier ("base"));
+                                               
+                                               var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
+                                               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
+                                               
+                                               cinit.append (cdecl);
+                                       } else if (m.instance) {
+                                               cinit.append (create_method_type_check_statement (m, cl, true, "self"));
+                                       }
+                               }
+                               foreach (FormalParameter param in m.get_parameters ()) {
+                                       var t = param.type_reference.data_type;
+                                       if (t != null && t.is_reference_type () && !param.type_reference.is_out) {
+                                               var type_check = create_method_type_check_statement (m, t, param.type_reference.non_null, param.name);
+                                               if (type_check != null) {
+                                                       cinit.append (type_check);
+                                               }
+                                       }
+                               }
+
+                               if (m.source_reference != null && m.source_reference.comment != null) {
+                                       source_type_member_definition.append (new CCodeComment (m.source_reference.comment));
+                               }
+                               source_type_member_definition.append (function);
+                               
+                               if (m is CreationMethod) {
+                                       if (current_class != null) {
+                                               int n_params = ((CreationMethod) m).n_construction_params;
+                                               n_params += (int) current_class.get_type_parameters ().length ();
+
+                                               // declare construction parameter array
+                                               var cparamsinit = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
+                                               cparamsinit.add_argument (new CCodeIdentifier ("GParameter"));
+                                               cparamsinit.add_argument (new CCodeConstant (n_params.to_string ()));
+                                               
+                                               var cdecl = new CCodeDeclaration ("GParameter *");
+                                               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params", cparamsinit));
+                                               cinit.append (cdecl);
+                                               
+                                               cdecl = new CCodeDeclaration ("GParameter *");
+                                               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params_it", new CCodeIdentifier ("__params")));
+                                               cinit.append (cdecl);
+
+                                               /* destroy func properties for generic types */
+                                               foreach (TypeParameter type_param in current_class.get_type_parameters ()) {
+                                                       string func_name = "%s_destroy_func".printf (type_param.name.down ());
+                                                       var func_name_constant = new CCodeConstant ("\"%s-destroy-func\"".printf (type_param.name.down ()));
+
+                                                       // this property is used as a construction parameter
+                                                       var cpointer = new CCodeIdentifier ("__params_it");
+
+                                                       var ccomma = new CCodeCommaExpression ();
+                                                       // set name in array for current parameter
+                                                       var cnamemember = new CCodeMemberAccess.pointer (cpointer, "name");
+                                                       ccomma.append_expression (new CCodeAssignment (cnamemember, func_name_constant));
+                                                       var gvaluearg = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeMemberAccess.pointer (cpointer, "value"));
+
+                                                       // initialize GValue in array for current parameter
+                                                       var cvalueinit = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
+                                                       cvalueinit.add_argument (gvaluearg);
+                                                       cvalueinit.add_argument (new CCodeIdentifier ("G_TYPE_POINTER"));
+                                                       ccomma.append_expression (cvalueinit);
+
+                                                       // set GValue for current parameter
+                                                       var cvalueset = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_pointer"));
+                                                       cvalueset.add_argument (gvaluearg);
+                                                       cvalueset.add_argument (new CCodeIdentifier (func_name));
+                                                       ccomma.append_expression (cvalueset);
+
+                                                       // move pointer to next parameter in array
+                                                       ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, cpointer));
+
+                                                       cinit.append (new CCodeExpressionStatement (ccomma));
+                                               }
+                                       } else {
+                                               var st = (Struct) m.symbol.parent_symbol.node;
+                                               var cdecl = new CCodeDeclaration (st.get_cname () + "*");
+                                               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
+                                               ccall.add_argument (new CCodeConstant (st.get_cname ()));
+                                               ccall.add_argument (new CCodeConstant ("1"));
+                                               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
+                                               cinit.append (cdecl);
+                                       }
+                               }
+
+                               if (context.module_init_method == m && in_plugin) {
+                                       // GTypeModule-based plug-in, register types
+                                       cinit.append (module_init_fragment);
+                               }
+                       }
+               }
+               
+               if (m.is_abstract || m.is_virtual) {
+                       var vfunc = new CCodeFunction (m.get_cname (), m.return_type.get_cname ());
+
+                       var this_type = new TypeReference ();
+                       this_type.data_type = (DataType) m.symbol.parent_symbol.node;
+
+                       var cparam = new CCodeFormalParameter ("self", this_type.get_cname ());
+                       vfunc.add_parameter (cparam);
+                       
+                       var vblock = new CCodeBlock ();
+                       
+                       CCodeFunctionCall vcast = null;
+                       if (m.symbol.parent_symbol.node is Interface) {
+                               var iface = (Interface) m.symbol.parent_symbol.node;
+
+                               vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_INTERFACE".printf (iface.get_upper_case_cname (null))));
+                       } else {
+                               var cl = (Class) m.symbol.parent_symbol.node;
+
+                               vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS".printf (cl.get_upper_case_cname (null))));
+                       }
+                       vcast.add_argument (new CCodeIdentifier ("self"));
+               
+                       var vcall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, m.name));
+                       vcall.add_argument (new CCodeIdentifier ("self"));
+               
+                       var params = m.get_parameters ();
+                       foreach (FormalParameter param in params) {
+                               vfunc.add_parameter ((CCodeFormalParameter) param.ccodenode);
+                               vcall.add_argument (new CCodeIdentifier (param.name));
+                       }
+
+                       if (m.return_type.data_type == null) {
+                               vblock.add_statement (new CCodeExpressionStatement (vcall));
+                       } else {
+                               /* pass method return value */
+                               vblock.add_statement (new CCodeReturnStatement (vcall));
+                       }
+
+                       header_type_member_declaration.append (vfunc.copy ());
+                       
+                       vfunc.block = vblock;
+                       
+                       source_type_member_definition.append (vfunc);
+               }
+               
+               if (m is CreationMethod) {
+                       var creturn = new CCodeReturnStatement ();
+                       creturn.return_expression = new CCodeIdentifier ("self");
+                       function.block.add_statement (creturn);
+               }
+               
+               bool return_value = true;
+               bool args_parameter = true;
+               if (is_possible_entry_point (m, ref return_value, ref args_parameter)) {
+                       // m is possible entry point, add appropriate startup code
+                       var cmain = new CCodeFunction ("main", "int");
+                       cmain.add_parameter (new CCodeFormalParameter ("argc", "int"));
+                       cmain.add_parameter (new CCodeFormalParameter ("argv", "char **"));
+                       var main_block = new CCodeBlock ();
+                       main_block.add_statement (new CCodeExpressionStatement (new CCodeFunctionCall (new CCodeIdentifier ("g_type_init"))));
+                       var main_call = new CCodeFunctionCall (new CCodeIdentifier (function.name));
+                       if (args_parameter) {
+                               main_call.add_argument (new CCodeIdentifier ("argc"));
+                               main_call.add_argument (new CCodeIdentifier ("argv"));
+                       }
+                       if (return_value) {
+                               main_block.add_statement (new CCodeReturnStatement (main_call));
+                       } else {
+                               // method returns void, always use 0 as exit code
+                               main_block.add_statement (new CCodeExpressionStatement (main_call));
+                               main_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("0")));
+                       }
+                       cmain.block = main_block;
+                       source_type_member_definition.append (cmain);
+               }
+       }
+       
+       public override void visit_begin_creation_method (CreationMethod! m) {
+               current_symbol = m.symbol;
+               current_return_type = m.return_type;
+               in_creation_method = true;
+       }
+       
+       public override void visit_end_creation_method (CreationMethod! m) {
+               if (current_class != null && m.body != null) {
+                       add_object_creation ((CCodeBlock) m.body.ccodenode);
+               }
+
+               in_creation_method = false;
+
+               visit_end_method (m);
+       }
+       
+       private bool is_possible_entry_point (Method! m, ref bool return_value, ref bool args_parameter) {
+               if (m.name == null || m.name != "main") {
+                       // method must be called "main"
+                       return false;
+               }
+               
+               if (m.instance) {
+                       // method must be static
+                       return false;
+               }
+               
+               if (m.return_type.data_type == null) {
+                       return_value = false;
+               } else if (m.return_type.data_type == int_type.data_type) {
+                       return_value = true;
+               } else {
+                       // return type must be void or int
+                       return false;
+               }
+               
+               var params = m.get_parameters ();
+               if (params.length () == 0) {
+                       // method may have no parameters
+                       args_parameter = false;
+                       return true;
+               }
+               
+               if (params.length () > 1) {
+                       // method must not have more than one parameter
+                       return false;
+               }
+               
+               var param = (FormalParameter) params.data;
+
+               if (param.type_reference.is_out) {
+                       // parameter must not be an out parameter
+                       return false;
+               }
+               
+               if (!(param.type_reference.data_type is Array)) {
+                       // parameter must be an array
+                       return false;
+               }
+               
+               var array_type = (Array) param.type_reference.data_type;
+               if (array_type.element_type != string_type.data_type) {
+                       // parameter must be an array of strings
+                       return false;
+               }
+               
+               args_parameter = true;
+               return true;
+       }
+}
+
diff --git a/gobject/valacodegeneratorsignal.vala b/gobject/valacodegeneratorsignal.vala
new file mode 100644 (file)
index 0000000..bada079
--- /dev/null
@@ -0,0 +1,237 @@
+/* valacodegeneratorsignal.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>
+ */
+
+using GLib;
+
+public class Vala.CodeGenerator {
+       private string get_marshaller_type_name (TypeReference t) {
+               if (t.type_parameter != null) {
+                       return ("POINTER");
+               } else if (t.data_type == null) {
+                       return ("VOID");
+               } else {
+                       return t.data_type.get_marshaller_type_name ();
+               }
+       }
+       
+       private ref string get_signal_marshaller_function (Signal! sig, string prefix = null) {
+               var signature = get_signal_signature (sig);
+               string ret;
+               var params = sig.get_parameters ();
+               
+               if (prefix == null) {
+                       // FIXME remove equality check with cast in next revision
+                       if (predefined_marshal_list.lookup (signature) != (bool) null) {
+                               prefix = "g_cclosure_marshal";
+                       } else {
+                               prefix = "g_cclosure_user_marshal";
+                       }
+               }
+               
+               ret = "%s_%s_".printf (prefix, get_marshaller_type_name (sig.return_type));
+               
+               if (params == null) {
+                       ret = ret + "_VOID";
+               } else {
+                       foreach (FormalParameter p in params) {
+                               ret = "%s_%s".printf (ret, get_marshaller_type_name (p.type_reference));
+                       }
+               }
+               
+               return ret;
+       }
+       
+       private string get_value_type_name_from_type_reference (TypeReference! t) {
+               if (t.type_parameter != null) {
+                       return "gpointer";
+               } else if (t.data_type == null) {
+                       return "void";
+               } else if (t.data_type is Class || t.data_type is Interface) {
+                       return "GObject *";
+               } else if (t.data_type is Struct) {
+                       if (((Struct) t.data_type).is_reference_type ()) {
+                               return "gpointer";
+                       } else {
+                               return t.data_type.get_cname ();
+                       }
+               } else if (t.data_type is Enum) {
+                       return "gint";
+               } else if (t.data_type is Flags) {
+                       return "guint";
+               } else if (t.data_type is Array) {
+                       return "gpointer";
+               }
+               
+               return null;
+       }
+       
+       private ref string get_signal_signature (Signal! sig) {
+               string signature;
+               var params = sig.get_parameters ();
+               
+               signature = "%s:".printf (get_marshaller_type_name (sig.return_type));
+               if (params == null) {
+                       signature = signature + "VOID";
+               } else {
+                       bool first = true;
+                       foreach (FormalParameter p in params) {
+                               if (first) {
+                                       signature = signature + get_marshaller_type_name (p.type_reference);
+                                       first = false;
+                               } else {
+                                       signature = "%s,%s".printf (signature, get_marshaller_type_name (p.type_reference));
+                               }
+                       }
+               }
+               
+               return signature;
+       }
+       
+       public override void visit_end_signal (Signal! sig) {
+               string signature;
+               var params = sig.get_parameters ();
+               int n_params, i;
+               
+               /* check whether a signal with the same signature already exists for this source file (or predefined) */
+               signature = get_signal_signature (sig);
+               // FIXME remove equality checks with cast in next revision
+               if (predefined_marshal_list.lookup (signature) != (bool) null || user_marshal_list.lookup (signature) != (bool) null) {
+                       return;
+               }
+               
+               var signal_marshaller = new CCodeFunction (get_signal_marshaller_function (sig), "void");
+               signal_marshaller.modifiers = CCodeModifiers.STATIC;
+               
+               signal_marshaller.add_parameter (new CCodeFormalParameter ("closure", "GClosure *"));
+               signal_marshaller.add_parameter (new CCodeFormalParameter ("return_value", "GValue *"));
+               signal_marshaller.add_parameter (new CCodeFormalParameter ("n_param_values", "guint"));
+               signal_marshaller.add_parameter (new CCodeFormalParameter ("param_values", "const GValue *"));
+               signal_marshaller.add_parameter (new CCodeFormalParameter ("invocation_hint", "gpointer"));
+               signal_marshaller.add_parameter (new CCodeFormalParameter ("marshal_data", "gpointer"));
+               
+               source_signal_marshaller_declaration.append (signal_marshaller.copy ());
+               
+               var marshaller_body = new CCodeBlock ();
+               
+               var callback_decl = new CCodeFunctionDeclarator (get_signal_marshaller_function (sig, "GMarshalFunc"));
+               callback_decl.add_parameter (new CCodeFormalParameter ("data1", "gpointer"));
+               n_params = 1;
+               foreach (FormalParameter p in params) {
+                       callback_decl.add_parameter (new CCodeFormalParameter ("arg_%d".printf (n_params), get_value_type_name_from_type_reference (p.type_reference)));
+                       n_params++;
+               }
+               callback_decl.add_parameter (new CCodeFormalParameter ("data2", "gpointer"));
+               marshaller_body.add_statement (new CCodeTypeDefinition (get_value_type_name_from_type_reference (sig.return_type), callback_decl));
+               
+               var var_decl = new CCodeDeclaration (get_signal_marshaller_function (sig, "GMarshalFunc"));
+               var_decl.modifiers = CCodeModifiers.REGISTER;
+               var_decl.add_declarator (new CCodeVariableDeclarator ("callback"));
+               marshaller_body.add_statement (var_decl);
+               
+               var_decl = new CCodeDeclaration ("GCClosure *");
+               var_decl.modifiers = CCodeModifiers.REGISTER;
+               var_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("cc", new CCodeCastExpression (new CCodeIdentifier ("closure"), "GCClosure *")));
+               marshaller_body.add_statement (var_decl);
+               
+               var_decl = new CCodeDeclaration ("gpointer");
+               var_decl.modifiers = CCodeModifiers.REGISTER;
+               var_decl.add_declarator (new CCodeVariableDeclarator ("data1"));
+               var_decl.add_declarator (new CCodeVariableDeclarator ("data2"));
+               marshaller_body.add_statement (var_decl);
+               
+               CCodeFunctionCall fc;
+               
+               if (sig.return_type.data_type != null) {
+                       var_decl = new CCodeDeclaration (get_value_type_name_from_type_reference (sig.return_type));
+                       var_decl.add_declarator (new CCodeVariableDeclarator ("v_return"));
+                       marshaller_body.add_statement (var_decl);
+                       
+                       fc = new CCodeFunctionCall (new CCodeIdentifier ("g_return_if_fail"));
+                       fc.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("return_value"), new CCodeConstant ("NULL")));
+                       marshaller_body.add_statement (new CCodeExpressionStatement (fc));
+               }
+               
+               fc = new CCodeFunctionCall (new CCodeIdentifier ("g_return_if_fail"));
+               fc.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier ("n_param_values"), new CCodeConstant (n_params.to_string())));
+               marshaller_body.add_statement (new CCodeExpressionStatement (fc));
+               
+               var data = new CCodeMemberAccess (new CCodeIdentifier ("closure"), "data", true);
+               var param = new CCodeMemberAccess (new CCodeMemberAccess (new CCodeIdentifier ("param_values"), "data[0]", true), "v_pointer");
+               var cond = new CCodeFunctionCall (new CCodeConstant ("G_CCLOSURE_SWAP_DATA"));
+               cond.add_argument (new CCodeIdentifier ("closure"));
+               var true_block = new CCodeBlock ();
+               true_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data1"), data)));
+               true_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data2"), param)));
+               var false_block = new CCodeBlock ();
+               false_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data1"), param)));
+               false_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data2"), data)));
+               marshaller_body.add_statement (new CCodeIfStatement (cond, true_block, false_block));
+               
+               var c_assign = new CCodeAssignment (new CCodeIdentifier ("callback"), new CCodeCastExpression (new CCodeConditionalExpression (new CCodeIdentifier ("marshal_data"), new CCodeIdentifier ("marshal_data"), new CCodeMemberAccess (new CCodeIdentifier ("cc"), "callback", true)), get_signal_marshaller_function (sig, "GMarshalFunc")));
+               marshaller_body.add_statement (new CCodeExpressionStatement (c_assign));
+               
+               fc = new CCodeFunctionCall (new CCodeIdentifier ("callback"));
+               fc.add_argument (new CCodeIdentifier ("data1"));
+               i = 1;
+               foreach (FormalParameter p in params) {
+                       string get_value_function;
+                       if (p.type_reference.type_parameter != null) {
+                               get_value_function = "g_value_get_pointer";
+                       } else {
+                               get_value_function = p.type_reference.data_type.get_get_value_function ();
+                       }
+                       var inner_fc = new CCodeFunctionCall (new CCodeIdentifier (get_value_function));
+                       inner_fc.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("param_values"), new CCodeIdentifier (i.to_string ())));
+                       fc.add_argument (inner_fc);
+                       i++;
+               }
+               fc.add_argument (new CCodeIdentifier ("data2"));
+               
+               if (sig.return_type.data_type != null) {
+                       marshaller_body.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("v_return"), fc)));
+                       
+                       CCodeFunctionCall set_fc;
+                       if (sig.return_type.type_parameter != null) {
+                               set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_pointer"));
+                       } else if (sig.return_type.data_type is Class || sig.return_type.data_type is Interface) {
+                               set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_object"));
+                       } else if (sig.return_type.data_type == string_type.data_type) {
+                               set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_string"));
+                       } else {
+                               set_fc = new CCodeFunctionCall (new CCodeIdentifier (sig.return_type.data_type.get_set_value_function ()));
+                       }
+                       set_fc.add_argument (new CCodeIdentifier ("return_value"));
+                       set_fc.add_argument (new CCodeIdentifier ("v_return"));
+                       
+                       marshaller_body.add_statement (new CCodeExpressionStatement (set_fc));
+               } else {
+                       marshaller_body.add_statement (new CCodeExpressionStatement (fc));
+               }
+               
+               signal_marshaller.block = marshaller_body;
+               
+               source_signal_marshaller_definition.append (signal_marshaller);
+               user_marshal_list.insert (signature, true);
+       }
+}
+
diff --git a/gobject/valacodegeneratorsourcefile.vala b/gobject/valacodegeneratorsourcefile.vala
new file mode 100644 (file)
index 0000000..b5bd643
--- /dev/null
@@ -0,0 +1,194 @@
+/* valacodegeneratorsourcefile.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>
+ */
+
+using GLib;
+
+public class Vala.CodeGenerator {
+       private ref CCodeIncludeDirective get_internal_include (string! filename) {
+               return new CCodeIncludeDirective (filename, context.library == null);
+       }
+
+       public override void visit_begin_source_file (SourceFile! source_file) {
+               header_begin = new CCodeFragment ();
+               header_type_declaration = new CCodeFragment ();
+               header_type_definition = new CCodeFragment ();
+               header_type_member_declaration = new CCodeFragment ();
+               source_begin = new CCodeFragment ();
+               source_include_directives = new CCodeFragment ();
+               source_type_member_declaration = new CCodeFragment ();
+               source_type_member_definition = new CCodeFragment ();
+               source_signal_marshaller_definition = new CCodeFragment ();
+               source_signal_marshaller_declaration = new CCodeFragment ();
+               
+               user_marshal_list = new HashTable (str_hash, str_equal);
+               
+               next_temp_var_id = 0;
+               
+               string_h_needed = false;
+               
+               header_begin.append (new CCodeIncludeDirective ("glib.h"));
+               header_begin.append (new CCodeIncludeDirective ("glib-object.h"));
+               source_include_directives.append (new CCodeIncludeDirective (source_file.get_cheader_filename (), true));
+               
+               ref List<weak string> used_includes = null;
+               used_includes.append ("glib.h");
+               used_includes.append ("glib-object.h");
+               used_includes.append (source_file.get_cheader_filename ());
+               
+               foreach (string filename1 in source_file.get_header_external_includes ()) {
+                       if (used_includes.find_custom (filename1, strcmp) == null) {
+                               header_begin.append (new CCodeIncludeDirective (filename1));
+                               used_includes.append (filename1);
+                       }
+               }
+               foreach (string filename2 in source_file.get_header_internal_includes ()) {
+                       if (used_includes.find_custom (filename2, strcmp) == null) {
+                               header_begin.append (get_internal_include (filename2));
+                               used_includes.append (filename2);
+                       }
+               }
+               foreach (string filename3 in source_file.get_source_external_includes ()) {
+                       if (used_includes.find_custom (filename3, strcmp) == null) {
+                               source_include_directives.append (new CCodeIncludeDirective (filename3));
+                               used_includes.append (filename3);
+                       }
+               }
+               foreach (string filename4 in source_file.get_source_internal_includes ()) {
+                       if (used_includes.find_custom (filename4, strcmp) == null) {
+                               source_include_directives.append (get_internal_include (filename4));
+                               used_includes.append (filename4);
+                       }
+               }
+               if (source_file.is_cycle_head) {
+                       foreach (SourceFile cycle_file in source_file.cycle.files) {
+                               var namespaces = cycle_file.get_namespaces ();
+                               foreach (Namespace ns in namespaces) {
+                                       var structs = ns.get_structs ();
+                                       foreach (Struct st in structs) {
+                                               header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (st.get_cname ()), new CCodeVariableDeclarator (st.get_cname ())));
+                                       }
+                                       var classes = ns.get_classes ();
+                                       foreach (Class cl in classes) {
+                                               header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (cl.get_cname ()), new CCodeVariableDeclarator (cl.get_cname ())));
+                                               header_type_declaration.append (new CCodeTypeDefinition ("struct _%sClass".printf (cl.get_cname ()), new CCodeVariableDeclarator ("%sClass".printf (cl.get_cname ()))));
+                                       }
+                                       var ifaces = ns.get_interfaces ();
+                                       foreach (Interface iface in ifaces) {
+                                               header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (iface.get_cname ()), new CCodeVariableDeclarator (iface.get_cname ())));
+                                               header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (iface.get_type_cname ()), new CCodeVariableDeclarator (iface.get_type_cname ())));
+                                       }
+                               }
+                       }
+               }
+               
+               /* generate hardcoded "well-known" macros */
+               source_begin.append (new CCodeMacroReplacement ("VALA_FREE_CHECKED(o,f)", "((o) == NULL ? NULL : ((o) = (f (o), NULL)))"));
+               source_begin.append (new CCodeMacroReplacement ("VALA_FREE_UNCHECKED(o,f)", "((o) = (f (o), NULL))"));
+       }
+       
+       private static ref string get_define_for_filename (string! filename) {
+               var define = new String ("__");
+               
+               var i = filename;
+               while (i.len () > 0) {
+                       var c = i.get_char ();
+                       if (c.isalnum  () && c < 0x80) {
+                               define.append_unichar (c.toupper ());
+                       } else {
+                               define.append_c ('_');
+                       }
+               
+                       i = i.next_char ();
+               }
+               
+               define.append ("__");
+               
+               return define.str;
+       }
+       
+       public override void visit_end_source_file (SourceFile! source_file) {
+               var header_define = get_define_for_filename (source_file.get_cheader_filename ());
+               
+               if (string_h_needed) {
+                       source_include_directives.append (new CCodeIncludeDirective ("string.h"));
+               }
+               
+               CCodeComment comment = null;
+               if (source_file.comment != null) {
+                       comment = new CCodeComment (source_file.comment);
+               }
+
+               var writer = new CCodeWriter (source_file.get_cheader_filename ());
+               if (comment != null) {
+                       comment.write (writer);
+               }
+               writer.write_newline ();
+               var once = new CCodeOnceSection (header_define);
+               once.append (new CCodeNewline ());
+               once.append (header_begin);
+               once.append (new CCodeNewline ());
+               once.append (new CCodeIdentifier ("G_BEGIN_DECLS"));
+               once.append (new CCodeNewline ());
+               once.append (new CCodeNewline ());
+               once.append (header_type_declaration);
+               once.append (new CCodeNewline ());
+               once.append (header_type_definition);
+               once.append (new CCodeNewline ());
+               once.append (header_type_member_declaration);
+               once.append (new CCodeNewline ());
+               once.append (new CCodeIdentifier ("G_END_DECLS"));
+               once.append (new CCodeNewline ());
+               once.append (new CCodeNewline ());
+               once.write (writer);
+               writer.close ();
+               
+               writer = new CCodeWriter (source_file.get_csource_filename ());
+               if (comment != null) {
+                       comment.write (writer);
+               }
+               source_begin.write (writer);
+               writer.write_newline ();
+               source_include_directives.write (writer);
+               writer.write_newline ();
+               source_type_member_declaration.write (writer);
+               writer.write_newline ();
+               source_signal_marshaller_declaration.write (writer);
+               writer.write_newline ();
+               source_type_member_definition.write (writer);
+               writer.write_newline ();
+               source_signal_marshaller_definition.write (writer);
+               writer.write_newline ();
+               writer.close ();
+
+               header_begin = null;
+               header_type_declaration = null;
+               header_type_definition = null;
+               header_type_member_declaration = null;
+               source_begin = null;
+               source_include_directives = null;
+               source_type_member_declaration = null;
+               source_type_member_definition = null;
+               source_signal_marshaller_definition = null;
+               source_signal_marshaller_declaration = null;
+       }
+}
diff --git a/gobject/valacodegeneratorstruct.vala b/gobject/valacodegeneratorstruct.vala
new file mode 100644 (file)
index 0000000..2176c04
--- /dev/null
@@ -0,0 +1,45 @@
+/* valacodegeneratorstruct.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>
+ */
+
+using GLib;
+
+public class Vala.CodeGenerator {
+       public override void visit_begin_struct (Struct! st) {
+               current_type_symbol = st.symbol;
+
+               instance_struct = new CCodeStruct ("_%s".printf (st.get_cname ()));
+
+               if (st.source_reference.file.cycle == null) {
+                       header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (st.get_cname ()), new CCodeVariableDeclarator (st.get_cname ())));
+               }
+
+               if (st.source_reference.comment != null) {
+                       header_type_definition.append (new CCodeComment (st.source_reference.comment));
+               }
+               header_type_definition.append (instance_struct);
+       }
+       
+       public override void visit_end_struct (Struct! st) {
+               current_type_symbol = null;
+       }
+}
index d82009d..04f241b 100644 (file)
@@ -31,7 +31,7 @@ vapigen.vala.stamp: $(filter %.vala,$(vapigen_SOURCES))
 
 vapigen_LDADD = \
        $(GLIB_LIBS) \
-       ../vala/libvala.la \
+       ../gobject/libvala.la \
        ../gobject-introspection/libgidl.la \
        $(NULL)