type check initializer lists
authorJuerg Billeter <j@bitron.ch>
Mon, 7 Apr 2008 16:16:46 +0000 (16:16 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Mon, 7 Apr 2008 16:16:46 +0000 (16:16 +0000)
2008-04-07  Juerg Billeter  <j@bitron.ch>

* vala/valasemanticanalyzer.vala: type check initializer lists

* gobject/valaccodegenerator.vala: fix support for static delegates
  for instance methods

* vapigen/valagidlparser.vala: support type_name metadata attribute
  for fields

* tests/test-031.vala: use float literals in initializer list for
  constant float array

* vapi/packages/gtk+-2.0/: fix GtkActionEntry.callback binding

* vapi/gtk+-2.0.vapi: regenerated

Fixes bug 526652

svn path=/trunk/; revision=1176

ChangeLog
gobject/valaccodegenerator.vala
tests/test-031.vala
vala/valadelegate.vala
vala/valasemanticanalyzer.vala
vapi/gtk+-2.0.vapi
vapi/packages/gtk+-2.0/gtk+-2.0-custom.vala
vapi/packages/gtk+-2.0/gtk+-2.0.metadata
vapigen/valagidlparser.vala

index e4abda8..b1bd68e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
 2008-04-07  Jürg Billeter  <j@bitron.ch>
 
+       * vala/valasemanticanalyzer.vala: type check initializer lists
+
+       * gobject/valaccodegenerator.vala: fix support for static delegates
+         for instance methods
+
+       * vapigen/valagidlparser.vala: support type_name metadata attribute
+         for fields
+
+       * tests/test-031.vala: use float literals in initializer list for
+         constant float array
+
+       * vapi/packages/gtk+-2.0/: fix GtkActionEntry.callback binding
+
+       * vapi/gtk+-2.0.vapi: regenerated
+
+       Fixes bug 526652
+
+2008-04-07  Jürg Billeter  <j@bitron.ch>
+
        * vapi/packages/gstreamer-0.10/: fix gst_init_get_option_group
          binding, fixes bug 526651
 
index 4badf98..5486957 100644 (file)
@@ -1166,15 +1166,11 @@ public class Vala.CCodeGenerator : CodeGenerator {
        public override void visit_initializer_list (InitializerList! list) {
                list.accept_children (this);
 
-               if (list.expected_type is ArrayType) {
-                       /* TODO */
-               } else {
-                       var clist = new CCodeInitializerList ();
-                       foreach (Expression expr in list.get_initializers ()) {
-                               clist.append ((CCodeExpression) expr.ccodenode);
-                       }
-                       list.ccodenode = clist;
+               var clist = new CCodeInitializerList ();
+               foreach (Expression expr in list.get_initializers ()) {
+                       clist.append (get_implicit_cast_expression ((CCodeExpression) expr.ccodenode, expr.static_type, expr.expected_type));
                }
+               list.ccodenode = clist;
        }
 
        public VariableDeclarator get_temp_variable_declarator (DataType! type, bool takes_ownership = true, CodeNode node_reference = null) {
@@ -3361,11 +3357,19 @@ public class Vala.CCodeGenerator : CodeGenerator {
 
                var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
 
+               int i = 0;
                if (m.instance) {
-                       carg_map.set (get_param_pos (m.cinstance_parameter_position), new CCodeIdentifier ("self"));
+                       CCodeExpression arg;
+                       if (d.instance) {
+                               arg = new CCodeIdentifier ("self");
+                       } else {
+                               // use first delegate parameter as instance
+                               arg = new CCodeIdentifier ((d_params.get (0).ccodenode as CCodeFormalParameter).name);
+                               i = 1;
+                       }
+                       carg_map.set (get_param_pos (m.cinstance_parameter_position), arg);
                }
 
-               int i = 0;
                foreach (FormalParameter param in m.get_parameters ()) {
                        CCodeExpression arg;
                        arg = new CCodeIdentifier ((d_params.get (i).ccodenode as CCodeFormalParameter).name);
index 665e94b..21a3d00 100644 (file)
@@ -2,7 +2,7 @@ using GLib;
 
 class Maman.Foo : Object {
        const float[] FLOAT_TESTS = { 
-               float.EPSILON, 0.0, 1.0
+               float.EPSILON, 0.0F, 1.0F
                -float.INFINITY,
                float.INFINITY,
                float.NAN
index 44ea182..c50bc26 100644 (file)
@@ -149,6 +149,7 @@ public class Vala.Delegate : Typesymbol {
         * @return  true if the specified method is compatible to this callback
         */
        public bool matches_method (Method! m) {
+               // method is allowed to ensure stricter return type (stronger postcondition)
                if (!m.return_type.stricter (return_type)) {
                        return false;
                }
@@ -170,7 +171,8 @@ public class Vala.Delegate : Typesymbol {
                        if (!method_params_it.next ()) {
                                break;
                        }
-                       
+
+                       // method is allowed to accept arguments of looser types (weaker precondition)
                        var method_param = method_params_it.get ();
                        if (!param.type_reference.stricter (method_param.type_reference)) {
                                return false;
index 2f0b435..20cc449 100644 (file)
@@ -307,12 +307,16 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        }
 
        public override void visit_constant (Constant! c) {
-               c.accept_children (this);
+               c.type_reference.accept (this);
 
                if (!current_source_file.pkg) {
                        if (c.initializer == null) {
                                c.error = true;
                                Report.error (c.source_reference, "A const field requires a initializer to be provided");
+                       } else {
+                               c.initializer.expected_type = c.type_reference;
+
+                               c.initializer.accept (this);
                        }
                }
        }
@@ -853,34 +857,64 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        foreach (Expression e in list.get_initializers ()) {
                                e.expected_type = array_type.element_type.copy ();
                        }
+               } else if (list.expected_type != null && list.expected_type.data_type is Struct) {
+                       /* initializer is used as struct initializer */
+                       var st = (Struct) list.expected_type.data_type;
+
+                       var field_it = st.get_fields ().iterator ();
+                       foreach (Expression e in list.get_initializers ()) {
+                               Field field = null;
+                               while (field == null) {
+                                       if (!field_it.next ()) {
+                                               list.error = true;
+                                               Report.error (e.source_reference, "too many expressions in initializer list for `%s'".printf (list.expected_type.to_string ()));
+                                               return;
+                                       }
+                                       field = field_it.get ();
+                                       if (!field.instance) {
+                                               // we only initialize instance fields
+                                               field = null;
+                                       }
+                               }
+
+                               e.expected_type = field.type_reference.copy ();
+                       }
+               } else if (list.expected_type == null) {
+                       list.error = true;
+                       Report.error (list.source_reference, "initializer list used for unknown type");
+                       return;
+               } else {
+                       list.error = true;
+                       Report.error (list.source_reference, "initializer list used for `%s', which is neither array nor struct".printf (list.expected_type.to_string ()));
+                       return;
                }
 
                list.accept_children (this);
 
-               if (list.expected_type is ArrayType) {
-                       var array_type = (ArrayType) list.expected_type;
+               bool error = false;
+               foreach (Expression e in list.get_initializers ()) {
+                       if (e.static_type == null) {
+                               error = true;
+                               continue;
+                       }
 
-                       bool error = false;
-                       foreach (Expression e in list.get_initializers ()) {
-                               if (e.static_type == null) {
+                       var unary = e as UnaryExpression;
+                       if (unary != null && (unary.operator == UnaryOperator.REF || unary.operator == UnaryOperator.OUT)) {
+                               // TODO check type for ref and out expressions
+                       } else if (!e.static_type.compatible (e.expected_type)) {
+                               if (!e.static_type.compatible (e.expected_type, false)) {
                                        error = true;
-                                       continue;
-                               }
-                               if (!e.static_type.compatible (array_type.element_type)) {
-                                       if (!e.static_type.compatible (array_type.element_type, false)) {
-                                               error = true;
-                                               e.error = true;
-                                               Report.error (e.source_reference, "Expected initializer of type `%s' but got `%s'".printf (array_type.element_type.data_type.name, e.static_type.to_string ()));
-                                       } else if (context.is_non_null_enabled ()) {
-                                               Report.warning (e.source_reference, "Expected initializer of type `%s' but got `%s'".printf (array_type.element_type.data_type.name, e.static_type.to_string ()));
-                                       }
+                                       e.error = true;
+                                       Report.error (e.source_reference, "Expected initializer of type `%s' but got `%s'".printf (e.expected_type.to_string (), e.static_type.to_string ()));
+                               } else if (context.is_non_null_enabled ()) {
+                                       Report.warning (e.source_reference, "Expected initializer of type `%s' but got `%s'".printf (e.expected_type.to_string (), e.static_type.to_string ()));
                                }
                        }
+               }
 
-                       if (!error) {
-                               /* everything seems to be correct */
-                               list.static_type = list.expected_type;
-                       }
+               if (!error) {
+                       /* everything seems to be correct */
+                       list.static_type = list.expected_type;
                }
        }
 
@@ -1605,7 +1639,10 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                }
                if (instance && !may_access_instance_members) {
                        expr.prototype_access = true;
-                       // no static type for prototype access
+
+                       // also set static type for prototype access
+                       // required when using instance methods as delegates in constants
+                       expr.static_type = get_static_type_for_symbol (expr.symbol_reference);
                } else {
                        expr.static_type = get_static_type_for_symbol (expr.symbol_reference);
 
index ac528da..cc234a1 100644 (file)
@@ -6098,7 +6098,7 @@ namespace Gtk {
                public weak string label;
                public weak string accelerator;
                public weak string tooltip;
-               public GLib.Callback callback;
+               public Gtk.ActionCallback callback;
        }
        [CCode (cheader_filename = "gtk/gtk.h")]
        public struct RadioActionEntry {
@@ -6271,6 +6271,8 @@ namespace Gtk {
        [CCode (cheader_filename = "gtk/gtk.h")]
        public static delegate void CallbackMarshal (Gtk.Object object, pointer data, Gtk.Arg[] args);
        [CCode (cheader_filename = "gtk/gtk.h")]
+       public delegate void ActionCallback (Gtk.Action action);
+       [CCode (cheader_filename = "gtk/gtk.h")]
        public delegate void AboutDialogActivateLinkFunc (Gtk.AboutDialog about, string link_);
        [CCode (cheader_filename = "gtk/gtk.h")]
        public static delegate bool AccelGroupActivate (Gtk.AccelGroup accel_group, GLib.Object acceleratable, uint keyval, Gdk.ModifierType modifier);
index c3facb6..a74de75 100644 (file)
@@ -49,4 +49,6 @@ namespace Gtk {
        }
 
        public static delegate void CallbackMarshal (Object object, pointer data, Arg[] args);
+
+       public delegate void ActionCallback (Action action);
 }
index 90992ca..b922a5b 100644 (file)
@@ -13,6 +13,7 @@ gtk_accelerator_parse.accelerator_key is_out="1"
 gtk_accelerator_parse.accelerator_mods is_out="1"
 GtkAction::activate has_emitter="1"
 GtkActionEntry is_value_type="1"
+GtkActionEntry.callback type_name="ActionCallback"
 gtk_action_group_add_actions.user_data hidden="0"
 gtk_action_group_add_actions_full.user_data hidden="0"
 gtk_action_group_add_toggle_actions.user_data hidden="0"
index af0224e..d0c9a43 100644 (file)
@@ -99,7 +99,7 @@ public class Vala.GIdlParser : CodeVisitor {
                current_source_file = source_file;
 
                codenode_attributes_map = new HashMap<string,string> (str_hash, str_equal);
-               codenode_attributes_patterns = new HashMap<pointer,string> (direct_hash, PatternSpec.equal);
+               codenode_attributes_patterns = new HashMap<pointer,string> (direct_hash, (EqualFunc) PatternSpec.equal);
 
                if (FileUtils.test (metadata_filename, FileTest.EXISTS)) {
                        try {
@@ -1538,6 +1538,8 @@ public class Vala.GIdlParser : CodeVisitor {
                                        if (eval (nv[1]) == "0") {
                                                type.takes_ownership = true;
                                        }
+                               } else if (nv[0] == "type_name") {
+                                       type.unresolved_symbol = new UnresolvedSymbol (null, eval (nv[1]));
                                }
                        }
                }