Fixes bug 571453.
private void add_object_creation (CCodeBlock b, bool has_params) {
var cl = (Class) current_type_symbol;
- bool chain_up = false;
- CreationMethod cm = null;
- if (cl.base_class != null) {
- cm = cl.base_class.default_construction_method as CreationMethod;
- if (cm != null && cm.get_parameters ().size == 0
- && cm.has_construct_function) {
- if (!has_params) {
- chain_up = true;
- }
- }
- }
-
- if (!has_params && !chain_up
- && cl.base_class != gobject_type) {
+ if (!has_params && cl.base_class != gobject_type) {
// possibly report warning or error about missing base call
}
var cdecl = new CCodeVariableDeclarator ("self");
- if (chain_up) {
- generate_method_declaration (cm, source_declarations);
-
- var ccall = new CCodeFunctionCall (new CCodeIdentifier (cm.get_real_cname ()));
- ccall.add_argument (new CCodeIdentifier ("object_type"));
- cdecl.initializer = new CCodeCastExpression (ccall, "%s*".printf (cl.get_cname ()));
+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_newv"));
+ ccall.add_argument (new CCodeIdentifier ("object_type"));
+ if (has_params) {
+ ccall.add_argument (new CCodeConstant ("__params_it - __params"));
+ ccall.add_argument (new CCodeConstant ("__params"));
} else {
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_newv"));
- ccall.add_argument (new CCodeIdentifier ("object_type"));
- if (has_params) {
- ccall.add_argument (new CCodeConstant ("__params_it - __params"));
- ccall.add_argument (new CCodeConstant ("__params"));
- } else {
- ccall.add_argument (new CCodeConstant ("0"));
- ccall.add_argument (new CCodeConstant ("NULL"));
- }
- cdecl.initializer = ccall;
+ ccall.add_argument (new CCodeConstant ("0"));
+ ccall.add_argument (new CCodeConstant ("NULL"));
}
+ cdecl.initializer = ccall;
var cdeclaration = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
cdeclaration.add_declarator (cdecl);
if (body != null) {
body.check (analyzer);
+
+ // ensure we chain up to base constructor
+ var cl = parent_symbol as Class;
+ if (!chain_up && cl != null && cl.base_class != null) {
+ if (cl.base_class.default_construction_method != null
+ && !cl.base_class.default_construction_method.has_construct_function) {
+ // chain up impossible
+ } else if (analyzer.context.profile == Profile.GOBJECT && cl.base_class == analyzer.object_type) {
+ // no chain up necessary for direct GObject subclasses
+ } else if (analyzer.context.profile == Profile.GOBJECT
+ && cl.is_subtype_of (analyzer.object_type)
+ && n_construction_params > 0) {
+ // no chain up when using GObject construct properties
+ } else if (cl.base_class.default_construction_method == null
+ || cl.base_class.default_construction_method.access == SymbolAccessibility.PRIVATE) {
+ Report.warning (source_reference, "unable to chain up to private base constructor");
+ } else if (cl.base_class.default_construction_method.get_required_arguments () > 0) {
+ Report.warning (source_reference, "unable to chain up to base constructor requiring arguments");
+ } else {
+ var old_insert_block = analyzer.insert_block;
+ analyzer.current_symbol = body;
+ analyzer.insert_block = body;
+
+ var stmt = new ExpressionStatement (new MethodCall (new BaseAccess (source_reference), source_reference), source_reference);
+ body.insert_statement (0, stmt);
+ stmt.check (analyzer);
+
+ analyzer.current_symbol = this;
+ analyzer.insert_block = old_insert_block;
+ }
+ }
}
analyzer.current_source_file = old_source_file;
return true;
}
+
+ public int get_required_arguments () {
+ int n = 0;
+ foreach (var param in parameters) {
+ if (param.default_expression != null) {
+ // optional argument
+ break;
+ }
+ n++;
+ }
+ return n;
+ }
}
// vim:sw=8 noet
/* valaunresolvedsymbol.vala
*
- * Copyright (C) 2008 Jürg Billeter
+ * Copyright (C) 2008-2009 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
public bool qualified { get; set; }
public UnresolvedSymbol (UnresolvedSymbol? inner, string name, SourceReference? source_reference = null) {
+ base (name, source_reference);
this.inner = inner;
- this.name = name;
- this.source_reference = source_reference;
}
public override string to_string () {