[vala] Ensure constructors are chained up



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]