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
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) {
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);
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
* @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;
}
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;
}
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);
}
}
}
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;
}
}
}
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);
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 {
[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);
}
public static delegate void CallbackMarshal (Object object, pointer data, Arg[] args);
+
+ public delegate void ActionCallback (Action action);
}
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"
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 {
if (eval (nv[1]) == "0") {
type.takes_ownership = true;
}
+ } else if (nv[0] == "type_name") {
+ type.unresolved_symbol = new UnresolvedSymbol (null, eval (nv[1]));
}
}
}