[vala] Support chaining up to constructors in structs



commit e42d65d7856ab1f9ab048daf5749951f7d1c9f20
Author: Jürg Billeter <j bitron ch>
Date:   Fri Jan 29 16:16:52 2010 +0100

    Support chaining up to constructors in structs
    
    Based on patch by Marc-André Lureau, fixes bug 606482.

 codegen/valaccodemethodcallmodule.vala |   12 ++++++++++--
 vala/valamethodcall.vala               |    9 +++++++++
 vala/valastructvaluetype.vala          |   27 +++++++++++++++++++++++++++
 3 files changed, 46 insertions(+), 2 deletions(-)
---
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index dc76893..d97b4cf 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -62,6 +62,12 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 			m = cl.default_construction_method;
 			generate_method_declaration (m, source_declarations);
 			ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname ()));
+		} else if (itype is StructValueType) {
+			// constructor
+			var st = (Struct) ((StructValueType) itype).type_symbol;
+			m = st.default_construction_method;
+			generate_method_declaration (m, source_declarations);
+			ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname ()));
 		} else if (itype is DelegateType) {
 			deleg = ((DelegateType) itype).delegate_symbol;
 		}
@@ -114,7 +120,7 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 			}
 		}
 
-		if (m is CreationMethod) {
+		if (m is CreationMethod && m.parent_symbol is Class) {
 			if (context.profile == Profile.GOBJECT) {
 				if (!((Class) m.parent_symbol).is_compact) {
 					ccall.add_argument (new CCodeIdentifier ("object_type"));
@@ -129,6 +135,8 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 					break;
 				}
 			}
+		} else if (m is CreationMethod && m.parent_symbol is Struct) {
+			ccall.add_argument (new CCodeIdentifier ("self"));
 		} else if (m != null && m.get_type_parameters ().size > 0) {
 			// generic method
 			add_generic_type_arguments (in_arg_map, ma.get_type_arguments (), expr);
@@ -244,7 +252,7 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 				param.accept (codegen);
 			}
 			head.generate_dynamic_method_wrapper ((DynamicMethod) m);
-		} else if (m is CreationMethod && context.profile == Profile.GOBJECT) {
+		} else if (m is CreationMethod && context.profile == Profile.GOBJECT && m.parent_symbol is Class) {
 			ccall_expr = new CCodeAssignment (new CCodeIdentifier ("self"), new CCodeCastExpression (ccall, current_class.get_cname () + "*"));
 
 			if (!current_class.is_compact && current_class.get_type_parameters ().size > 0) {
diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala
index 8ac74a9..55b6bff 100644
--- a/vala/valamethodcall.vala
+++ b/vala/valamethodcall.vala
@@ -186,6 +186,15 @@ public class Vala.MethodCall : Expression {
 		    ((call.symbol_reference is CreationMethod
 		      && call.symbol_reference.parent_symbol is Struct)
 		     || call.symbol_reference is Struct)) {
+			var cm = analyzer.find_current_method () as CreationMethod;
+			if (cm != null) {
+				if (cm.chain_up) {
+					error = true;
+					Report.error (source_reference, "Multiple constructor calls in the same constructor are not permitted");
+					return false;
+				}
+				cm.chain_up = true;
+			}
 			var struct_creation_expression = new ObjectCreationExpression ((MemberAccess) call, source_reference);
 			struct_creation_expression.struct_creation = true;
 			foreach (Expression arg in get_argument_list ()) {
diff --git a/vala/valastructvaluetype.vala b/vala/valastructvaluetype.vala
index dce8fca..52880a8 100644
--- a/vala/valastructvaluetype.vala
+++ b/vala/valastructvaluetype.vala
@@ -30,6 +30,33 @@ public class Vala.StructValueType : ValueType {
 		base (type_symbol);
 	}
 
+	public override bool is_invokable () {
+		var st = type_symbol as Struct;
+		if (st != null && st.default_construction_method != null) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	public override DataType? get_return_type () {
+		var st = type_symbol as Struct;
+		if (st != null && st.default_construction_method != null) {
+			return st.default_construction_method.return_type;
+		} else {
+			return null;
+		}
+	}
+
+	public override List<FormalParameter>? get_parameters () {
+		var st = type_symbol as Struct;
+		if (st != null && st.default_construction_method != null) {
+			return st.default_construction_method.get_parameters ();
+		} else {
+			return null;
+		}
+	}
+
 	public override DataType copy () {
 		var result = new StructValueType ((Struct) type_symbol);
 		result.source_reference = source_reference;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]