[vala] Ensure constructors are chained up
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [vala] Ensure constructors are chained up
- Date: Sun, 16 Aug 2009 19:05:34 +0000 (UTC)
commit 8aee994df85acd913547f932c1e5e7be7b90a690
Author: Jürg Billeter <j bitron ch>
Date: Sun Aug 16 19:19:38 2009 +0200
Ensure constructors are chained up
Fixes bug 571453.
codegen/valaccodemethodmodule.vala | 39 ++++++++---------------------------
vala/valacreationmethod.vala | 31 ++++++++++++++++++++++++++++
vala/valamethod.vala | 12 +++++++++++
vala/valaunresolvedsymbol.vala | 5 +--
4 files changed, 54 insertions(+), 33 deletions(-)
---
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index f4bbc5e..0ba3bc9 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -945,42 +945,21 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
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);
diff --git a/vala/valacreationmethod.vala b/vala/valacreationmethod.vala
index 7f78ae4..1279b96 100644
--- a/vala/valacreationmethod.vala
+++ b/vala/valacreationmethod.vala
@@ -150,6 +150,37 @@ public class Vala.CreationMethod : Method {
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;
diff --git a/vala/valamethod.vala b/vala/valamethod.vala
index 51ea569..3036f2a 100644
--- a/vala/valamethod.vala
+++ b/vala/valamethod.vala
@@ -899,6 +899,18 @@ public class Vala.Method : Member {
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
diff --git a/vala/valaunresolvedsymbol.vala b/vala/valaunresolvedsymbol.vala
index fcfaa3c..0c6c099 100644
--- a/vala/valaunresolvedsymbol.vala
+++ b/vala/valaunresolvedsymbol.vala
@@ -1,6 +1,6 @@
/* 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
@@ -35,9 +35,8 @@ public class Vala.UnresolvedSymbol : Symbol {
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 () {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]