]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
improve generic type resolution to support generic fields, fixes bug
authorJuerg Billeter <j@bitron.ch>
Wed, 23 Jan 2008 18:58:37 +0000 (18:58 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Wed, 23 Jan 2008 18:58:37 +0000 (18:58 +0000)
2008-01-23  Juerg Billeter  <j@bitron.ch>

* 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

ChangeLog
gobject/valaccodegenerator.vala
gobject/valaccodegeneratormemberaccess.vala
vala/valamethodtype.vala
vala/valasemanticanalyzer.vala
vala/valasignaltype.vala

index 12d4bea4f694e6d2aeb15954cc8b4d65d1d51d67..1b3a547595da3880c3020227a1708b9ff3d43dfc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-01-23  Jürg Billeter  <j@bitron.ch>
+
+       * 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  <j@bitron.ch>
 
        * vala/valadelegatetype.vala: fix symbol dependency for delegates,
index d899b60b8d024fb4cc355bba1d79aab172a8eb35..e4ca3b392097caa2605209a33907b40b7ceff8a6 100644 (file)
@@ -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;
        }
index 53bfb77c8d5347873e4474b9b4a156840edb6c20..10a4a6d9ef60566c9a0a650016e431a7a648c422 100644 (file)
@@ -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 ());
index f4b2cf54f45f6cfdb73992581dab4ee8e0f57c4e..2bd3b58d91017c3eb792320ac0977675b2936341 100644 (file)
@@ -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<FormalParameter> get_parameters () {
                return method_symbol.get_parameters ();
        }
+
+       public override DataType! copy () {
+               return new MethodType (method_symbol);
+       }
 }
index d83e5c12b4d62c176c212c6f8bcd8b56ee390e01..2d50e881bb7b14a9c11df0ae77d77682477637d7 100644 (file)
@@ -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");
index 3992f2e7fe18dc01fd55d1b8d8596d929ad09f72..0664c93e8e950821748577e6551529fb89c1354d 100644 (file)
@@ -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<FormalParameter> get_parameters () {
                return signal_symbol.get_parameters ();
        }
+
+       public override DataType! copy () {
+               return new SignalType (signal_symbol);
+       }
 }