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,
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))
}
}
}
-
- 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 ());
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));
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;
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;
}
}
- 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 ();
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;
- }
}
--- /dev/null
+/* 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;
+ }
+}
+
--- /dev/null
+/* 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);
+ }
+}
--- /dev/null
+/* 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);
+ }
+}
--- /dev/null
+/* 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;
+ }
+ }
+}
+
--- /dev/null
+/* 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);
+ }
+}
+
--- /dev/null
+/* 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;
+ }
+}
+
--- /dev/null
+/* 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);
+ }
+}
+
--- /dev/null
+/* 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;
+ }
+}
--- /dev/null
+/* 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;
+ }
+}
vapigen_LDADD = \
$(GLIB_LIBS) \
- ../vala/libvala.la \
+ ../gobject/libvala.la \
../gobject-introspection/libgidl.la \
$(NULL)