From: Juerg Billeter Date: Wed, 23 Jan 2008 18:58:37 +0000 (+0000) Subject: improve generic type resolution to support generic fields, fixes bug X-Git-Tag: VALA_0_1_7~194 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c41ef531b059f95617ebec950de5636e6b771d5f;p=thirdparty%2Fvala.git improve generic type resolution to support generic fields, fixes bug 2008-01-23 Juerg Billeter * vala/valamethodtype.vala, vala/valasemanticanalyzer.vala, vala/valasignaltype.vala, gobject/valaccodegenerator.vala, gobject/valaccodegeneratormemberaccess.vala: improve generic type resolution to support generic fields, fixes bug 475524 svn path=/trunk/; revision=897 --- diff --git a/ChangeLog b/ChangeLog index 12d4bea4f..1b3a54759 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-01-23 Jürg Billeter + + * vala/valamethodtype.vala, vala/valasemanticanalyzer.vala, + vala/valasignaltype.vala, gobject/valaccodegenerator.vala, + gobject/valaccodegeneratormemberaccess.vala: improve generic type + resolution to support generic fields, fixes bug 475524 + 2008-01-23 Jürg Billeter * vala/valadelegatetype.vala: fix symbol dependency for delegates, diff --git a/gobject/valaccodegenerator.vala b/gobject/valaccodegenerator.vala index d899b60b8..e4ca3b392 100644 --- a/gobject/valaccodegenerator.vala +++ b/gobject/valaccodegenerator.vala @@ -2923,6 +2923,8 @@ public class Vala.CCodeGenerator : CodeGenerator { cconv.add_argument (cexpr); result = cconv; } + } else if (actual_type.data_type != null && actual_type.data_type.is_reference_type ()) { + result = new CCodeCastExpression (cexpr, actual_type.get_cname ()); } return result; } diff --git a/gobject/valaccodegeneratormemberaccess.vala b/gobject/valaccodegeneratormemberaccess.vala index 53bfb77c8..10a4a6d9e 100644 --- a/gobject/valaccodegeneratormemberaccess.vala +++ b/gobject/valaccodegeneratormemberaccess.vala @@ -1,6 +1,6 @@ /* valaccodegeneratormemberaccess.vala * - * Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini + * Copyright (C) 2006-2008 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 @@ -96,6 +96,10 @@ public class Vala.CCodeGenerator { } else { expr.ccodenode = new CCodeIdentifier (f.get_cname ()); } + + if (f.type_reference.type_parameter != null && expr.static_type.type_parameter == null) { + expr.ccodenode = convert_from_generic_pointer ((CCodeExpression) expr.ccodenode, expr.static_type); + } } else if (expr.symbol_reference is Constant) { var c = (Constant) expr.symbol_reference; expr.ccodenode = new CCodeIdentifier (c.get_cname ()); diff --git a/vala/valamethodtype.vala b/vala/valamethodtype.vala index f4b2cf54f..2bd3b58d9 100644 --- a/vala/valamethodtype.vala +++ b/vala/valamethodtype.vala @@ -1,6 +1,6 @@ /* valamethodtype.vala * - * Copyright (C) 2007 Jürg Billeter + * Copyright (C) 2007-2008 Jürg Billeter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -43,4 +43,8 @@ public class Vala.MethodType : DataType { public override Collection get_parameters () { return method_symbol.get_parameters (); } + + public override DataType! copy () { + return new MethodType (method_symbol); + } } diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index d83e5c12b..2d50e881b 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -1511,6 +1511,16 @@ public class Vala.SemanticAnalyzer : CodeVisitor { // no static type for prototype access } else { expr.static_type = get_static_type_for_symbol (expr.symbol_reference); + + // resolve generic return values + if (expr.static_type != null && expr.static_type.type_parameter != null) { + if (expr.inner != null) { + expr.static_type = get_actual_type (expr.inner.static_type, expr.symbol_reference, expr.static_type, expr); + if (expr.static_type == null) { + return; + } + } + } } current_source_file.add_symbol_dependency (expr.symbol_reference, SourceFileDependencyType.SOURCE); @@ -1767,6 +1777,12 @@ public class Vala.SemanticAnalyzer : CodeVisitor { public static DataType get_actual_type (DataType derived_instance_type, Symbol generic_member, DataType generic_type, CodeNode node_reference) { DataType instance_type = derived_instance_type; + + while (instance_type is PointerType) { + var instance_pointer_type = (PointerType) instance_type; + instance_type = instance_pointer_type.base_type; + } + // trace type arguments back to the datatype where the method has been declared while (instance_type.data_type != generic_member.parent_symbol) { DataType instance_base_type = null; @@ -1795,6 +1811,14 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } } } + } else if (instance_type.data_type is Struct) { + var st = (Struct) instance_type.data_type; + foreach (DataType base_type in st.get_base_types ()) { + if (base_type.data_type.scope.lookup (generic_member.name) == generic_member) { + instance_base_type = get_instance_base_type (instance_type, base_type, node_reference); + break; + } + } } else if (instance_type.data_type is Interface) { var iface = (Interface) instance_type.data_type; // first check interface prerequisites recursively @@ -1824,9 +1848,16 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } if (instance_base_type == null) { + Report.error (node_reference.source_reference, "internal error: unable to find generic member `%s'".printf (generic_member.name)); + node_reference.error = true; return null; } instance_type = instance_base_type; + + while (instance_type is PointerType) { + var instance_pointer_type = (PointerType) instance_type; + instance_type = instance_pointer_type.base_type; + } } if (instance_type.data_type != generic_member.parent_symbol) { Report.error (node_reference.source_reference, "internal error: generic type parameter tracing not supported yet"); diff --git a/vala/valasignaltype.vala b/vala/valasignaltype.vala index 3992f2e7f..0664c93e8 100644 --- a/vala/valasignaltype.vala +++ b/vala/valasignaltype.vala @@ -1,6 +1,6 @@ /* valasignaltype.vala * - * Copyright (C) 2007 Jürg Billeter + * Copyright (C) 2007-2008 Jürg Billeter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -43,4 +43,8 @@ public class Vala.SignalType : DataType { public override Collection get_parameters () { return signal_symbol.get_parameters (); } + + public override DataType! copy () { + return new SignalType (signal_symbol); + } }