From: Juerg Billeter Date: Mon, 7 Apr 2008 16:16:46 +0000 (+0000) Subject: type check initializer lists X-Git-Tag: VALA_0_2_0~10 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=acb4cf6c50d17a0c1a12781aed0c958beb8e3ac5;p=platform%2Fupstream%2Fvala.git type check initializer lists 2008-04-07 Juerg Billeter * 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 --- diff --git a/ChangeLog b/ChangeLog index e4abda8..b1bd68e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,24 @@ 2008-04-07 Jürg Billeter + * 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 + * vapi/packages/gstreamer-0.10/: fix gst_init_get_option_group binding, fixes bug 526651 diff --git a/gobject/valaccodegenerator.vala b/gobject/valaccodegenerator.vala index 4badf98..5486957 100644 --- a/gobject/valaccodegenerator.vala +++ b/gobject/valaccodegenerator.vala @@ -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 (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); diff --git a/tests/test-031.vala b/tests/test-031.vala index 665e94b..21a3d00 100644 --- a/tests/test-031.vala +++ b/tests/test-031.vala @@ -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 diff --git a/vala/valadelegate.vala b/vala/valadelegate.vala index 44ea182..c50bc26 100644 --- a/vala/valadelegate.vala +++ b/vala/valadelegate.vala @@ -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; diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 2f0b435..20cc449 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -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); diff --git a/vapi/gtk+-2.0.vapi b/vapi/gtk+-2.0.vapi index ac528da..cc234a1 100644 --- a/vapi/gtk+-2.0.vapi +++ b/vapi/gtk+-2.0.vapi @@ -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); diff --git a/vapi/packages/gtk+-2.0/gtk+-2.0-custom.vala b/vapi/packages/gtk+-2.0/gtk+-2.0-custom.vala index c3facb6..a74de75 100644 --- a/vapi/packages/gtk+-2.0/gtk+-2.0-custom.vala +++ b/vapi/packages/gtk+-2.0/gtk+-2.0-custom.vala @@ -49,4 +49,6 @@ namespace Gtk { } public static delegate void CallbackMarshal (Object object, pointer data, Arg[] args); + + public delegate void ActionCallback (Action action); } diff --git a/vapi/packages/gtk+-2.0/gtk+-2.0.metadata b/vapi/packages/gtk+-2.0/gtk+-2.0.metadata index 90992ca..b922a5b 100644 --- a/vapi/packages/gtk+-2.0/gtk+-2.0.metadata +++ b/vapi/packages/gtk+-2.0/gtk+-2.0.metadata @@ -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" diff --git a/vapigen/valagidlparser.vala b/vapigen/valagidlparser.vala index af0224e..d0c9a43 100644 --- a/vapigen/valagidlparser.vala +++ b/vapigen/valagidlparser.vala @@ -99,7 +99,7 @@ public class Vala.GIdlParser : CodeVisitor { current_source_file = source_file; codenode_attributes_map = new HashMap (str_hash, str_equal); - codenode_attributes_patterns = new HashMap (direct_hash, PatternSpec.equal); + codenode_attributes_patterns = new HashMap (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])); } } }