From 4f224ceda5bf2c4eb5a215a6c5486af39d31b166 Mon Sep 17 00:00:00 2001 From: Juerg Billeter Date: Thu, 22 Nov 2007 08:53:01 +0000 Subject: [PATCH] add symbol dependency for generic type arguments 2007-11-22 Juerg Billeter * vala/valasemanticanalyzer.vala: add symbol dependency for generic type arguments * gobject/valaccodegenerator.vala, gobject/valaccodegeneratorclass.vala, gobject/valaccodegeneratormethod.vala: add type property for generic type parameters, support typeof for type parameters * configure.ac: require glib 2.12 for g_value_get_gtype svn path=/trunk/; revision=694 --- ChangeLog | 11 +++++++ configure.ac | 2 +- gobject/valaccodegenerator.vala | 14 ++++++++- gobject/valaccodegeneratorclass.vala | 57 ++++++++++++++++++++++++++++++----- gobject/valaccodegeneratormethod.vala | 8 ++++- vala/valasemanticanalyzer.vala | 4 +++ 6 files changed, 86 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7b4e1c1..b4a7609 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2007-11-22 Jürg Billeter + + * vala/valasemanticanalyzer.vala: add symbol dependency for generic + type arguments + + * gobject/valaccodegenerator.vala, gobject/valaccodegeneratorclass.vala, + gobject/valaccodegeneratormethod.vala: add type property for generic + type parameters, support typeof for type parameters + + * configure.ac: require glib 2.12 for g_value_get_gtype + 2007-11-21 Jürg Billeter * vapi/glib-2.0.vapi: add some more GObject functions diff --git a/configure.ac b/configure.ac index fd37e8e..e135de7 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,7 @@ AC_SUBST(LDFLAGS) AC_ARG_ENABLE(vapigen, AS_HELP_STRING([--enable-vapigen], [Enable VAPI generator]), enable_vapigen=$enableval, enable_vapigen=no) AM_CONDITIONAL(ENABLE_VAPIGEN, test x$enable_vapigen = xyes) -GLIB_REQUIRED=2.10.0 +GLIB_REQUIRED=2.12.0 ENCHANT_REQUIRED=1.3.0 PKG_CHECK_MODULES(GLIB, glib-2.0 >= $GLIB_REQUIRED gobject-2.0 >= $GLIB_REQUIRED) diff --git a/gobject/valaccodegenerator.vala b/gobject/valaccodegenerator.vala index dbdbf29..a6585fc 100644 --- a/gobject/valaccodegenerator.vala +++ b/gobject/valaccodegenerator.vala @@ -946,6 +946,17 @@ public class Vala.CCodeGenerator : CodeGenerator { return decl; } + private CCodeExpression get_type_id_expression (TypeReference! type) { + if (type.data_type != null) { + return new CCodeIdentifier (type.data_type.get_type_id ()); + } else if (type.type_parameter != null) { + string var_name = "%s_type".printf (type.type_parameter.name.down ()); + return new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), var_name); + } else { + return new CCodeIdentifier ("G_TYPE_NONE"); + } + } + private CCodeExpression get_dup_func_expression (TypeReference! type) { if (type.data_type != null) { string dup_function; @@ -2392,6 +2403,7 @@ public class Vala.CCodeGenerator : CodeGenerator { if (expr.type_reference.data_type is Class && expr.type_reference.data_type.is_subtype_of (gobject_type)) { foreach (TypeReference type_arg in expr.type_reference.get_type_arguments ()) { + creation_call.add_argument (get_type_id_expression (type_arg)); if (type_arg.takes_ownership) { creation_call.add_argument (new CCodeCastExpression (get_dup_func_expression (type_arg), "GBoxedCopyFunc")); creation_call.add_argument (get_destroy_func_expression (type_arg)); @@ -2516,7 +2528,7 @@ public class Vala.CCodeGenerator : CodeGenerator { } public override void visit_typeof_expression (TypeofExpression! expr) { - expr.ccodenode = new CCodeIdentifier (expr.type_reference.data_type.get_type_id ()); + expr.ccodenode = get_type_id_expression (expr.type_reference); } public override void visit_unary_expression (UnaryExpression! expr) { diff --git a/gobject/valaccodegeneratorclass.vala b/gobject/valaccodegeneratorclass.vala index 1c92e96..569e7ef 100644 --- a/gobject/valaccodegeneratorclass.vala +++ b/gobject/valaccodegeneratorclass.vala @@ -350,12 +350,31 @@ public class Vala.CCodeGenerator { } if (cl.is_subtype_of (gobject_type)) { - /* create dup_func and destroy_func properties for generic types */ + /* create type, dup_func, and destroy_func properties for generic types */ foreach (TypeParameter type_param in cl.get_type_parameters ()) { string func_name, enum_value; CCodeConstant func_name_constant; CCodeFunctionCall cinst, cspec; + func_name = "%s_type".printf (type_param.name.down ()); + func_name_constant = new CCodeConstant ("\"%s-type\"".printf (type_param.name.down ())); + enum_value = "%s_%s".printf (cl.get_lower_case_cname (null), func_name).up (); + cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_install_property")); + cinst.add_argument (ccall); + cinst.add_argument (new CCodeConstant (enum_value)); + cspec = new CCodeFunctionCall (new CCodeIdentifier ("g_param_spec_gtype")); + cspec.add_argument (func_name_constant); + cspec.add_argument (new CCodeConstant ("\"type\"")); + cspec.add_argument (new CCodeConstant ("\"type\"")); + cspec.add_argument (new CCodeIdentifier ("G_TYPE_NONE")); + cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE")); + cinst.add_argument (cspec); + init_block.add_statement (new CCodeExpressionStatement (cinst)); + prop_enum.add_value (new CCodeEnumValue (enum_value)); + + instance_priv_struct.add_field ("GType", func_name); + + func_name = "%s_dup_func".printf (type_param.name.down ()); func_name_constant = new CCodeConstant ("\"%s-dup-func\"".printf (type_param.name.down ())); enum_value = "%s_%s".printf (cl.get_lower_case_cname (null), func_name).up (); @@ -655,14 +674,38 @@ public class Vala.CCodeGenerator { block.add_statement (cswitch); - /* destroy func properties for generic types */ + /* type, dup func, and 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 (); + string func_name, enum_value; + CCodeCaseStatement ccase; + CCodeMemberAccess cfield; + CCodeFunctionCall cgetcall; + + func_name = "%s_type".printf (type_param.name.down ()); + enum_value = "%s_%s".printf (cl.get_lower_case_cname (null), func_name).up (); + ccase = new CCodeCaseStatement (new CCodeIdentifier (enum_value)); + cfield = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name); + cgetcall = new CCodeFunctionCall (new CCodeIdentifier ("g_value_get_gtype")); + cgetcall.add_argument (new CCodeIdentifier ("value")); + ccase.add_statement (new CCodeExpressionStatement (new CCodeAssignment (cfield, cgetcall))); + ccase.add_statement (new CCodeBreakStatement ()); + cswitch.add_case (ccase); + + func_name = "%s_dup_func".printf (type_param.name.down ()); + enum_value = "%s_%s".printf (cl.get_lower_case_cname (null), func_name).up (); + ccase = new CCodeCaseStatement (new CCodeIdentifier (enum_value)); + cfield = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name); + 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); - 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")); + func_name = "%s_destroy_func".printf (type_param.name.down ()); + enum_value = "%s_%s".printf (cl.get_lower_case_cname (null), func_name).up (); + ccase = new CCodeCaseStatement (new CCodeIdentifier (enum_value)); + cfield = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name); + 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 ()); diff --git a/gobject/valaccodegeneratormethod.vala b/gobject/valaccodegeneratormethod.vala index 14990b4..ed89308 100644 --- a/gobject/valaccodegeneratormethod.vala +++ b/gobject/valaccodegeneratormethod.vala @@ -151,6 +151,7 @@ public class Vala.CCodeGenerator { if (in_gobject_creation_method) { // memory management for generic types foreach (TypeParameter type_param in current_class.get_type_parameters ()) { + function.add_parameter (new CCodeFormalParameter ("%s_type".printf (type_param.name.down ()), "GType")); function.add_parameter (new CCodeFormalParameter ("%s_dup_func".printf (type_param.name.down ()), "GBoxedCopyFunc")); function.add_parameter (new CCodeFormalParameter ("%s_destroy_func".printf (type_param.name.down ()), "GDestroyNotify")); } @@ -300,12 +301,17 @@ public class Vala.CCodeGenerator { cinit.append (cdecl); } - /* dup and destroy func properties for generic types */ + /* type, dup func, and destroy func properties for generic types */ foreach (TypeParameter type_param in current_class.get_type_parameters ()) { string func_name; CCodeMemberAccess cmember; CCodeAssignment cassign; + func_name = "%s_type".printf (type_param.name.down ()); + cmember = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name); + cassign = new CCodeAssignment (cmember, new CCodeIdentifier (func_name)); + function.block.add_statement (new CCodeExpressionStatement (cassign)); + func_name = "%s_dup_func".printf (type_param.name.down ()); cmember = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name); cassign = new CCodeAssignment (cmember, new CCodeIdentifier (func_name)); diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index bd32a90..b4f5ba2 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -1921,6 +1921,10 @@ public class Vala.SemanticAnalyzer : CodeVisitor { expr.type_reference.data_type = type; foreach (TypeReference type_arg in type_args) { expr.type_reference.add_type_argument (type_arg); + + if (type_arg.data_type != null) { + current_source_file.add_symbol_dependency (type_arg.data_type, SourceFileDependencyType.SOURCE); + } } } else { type = expr.type_reference.data_type; -- 2.7.4