/* valaccodemethodmodule.vala
*
- * Copyright (C) 2007-2009 Jürg Billeter
+ * Copyright (C) 2007-2010 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
if (m is CreationMethod) {
if (in_gobject_creation_method && m.body != null) {
- if (!((CreationMethod) m).chain_up) {
- if (m.body.captured) {
- Report.error (m.source_reference, "Closures are not supported in GObject-style creation methods");
- }
-
- var cblock = new CCodeBlock ();
-
- // last property assignment statement
- CodeNode last_stmt = null;
-
- // set construct properties
- foreach (CodeNode stmt in m.body.get_statements ()) {
- var expr_stmt = stmt as ExpressionStatement;
- if (expr_stmt != null) {
- var prop = expr_stmt.assigned_property ();
- if (prop != null && prop.set_accessor.construction) {
- last_stmt = stmt;
- }
- }
- }
- if (last_stmt != null) {
- foreach (CodeNode stmt in m.body.get_statements ()) {
- if (stmt.ccodenode is CCodeFragment) {
- foreach (CCodeNode cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
- cblock.add_statement (cstmt);
- }
- } else {
- cblock.add_statement (stmt.ccodenode);
- }
- if (last_stmt == stmt) {
- break;
- }
- }
- }
-
- add_object_creation (cblock, ((CreationMethod) m).n_construction_params > 0 || current_class.get_type_parameters ().size > 0);
+ var cblock = (CCodeBlock) m.body.ccodenode;
- // other initialization code
- foreach (CodeNode stmt in m.body.get_statements ()) {
- if (last_stmt != null) {
- if (last_stmt == stmt) {
- last_stmt = null;
- }
- continue;
- }
- if (stmt.ccodenode is CCodeFragment) {
- foreach (CCodeNode cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
- cblock.add_statement (cstmt);
- }
- } else {
- cblock.add_statement (stmt.ccodenode);
- }
- }
-
- foreach (LocalVariable local in m.body.get_local_variables ()) {
- if (!local.floating && requires_destroy (local.variable_type)) {
- var ma = new MemberAccess.simple (local.name);
- ma.symbol_reference = local;
- ma.value_type = local.variable_type.copy ();
- cblock.add_statement (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
- }
- }
-
- m.body.ccodenode = cblock;
+ if (!((CreationMethod) m).chain_up) {
+ prepend_object_creation (cblock, current_class.get_type_parameters ().size > 0);
} else {
- var cblock = (CCodeBlock) m.body.ccodenode;
-
var cdeclaration = new CCodeDeclaration ("%s *".printf (((Class) current_type_symbol).get_cname ()));
cdeclaration.add_declarator (new CCodeVariableDeclarator ("self"));
if (m is CreationMethod) {
if (in_gobject_creation_method) {
- int n_params = ((CreationMethod) m).n_construction_params;
-
if (!((CreationMethod) m).chain_up) {
- if (n_params > 0 || current_class.get_type_parameters ().size > 0) {
+ if (current_class.get_type_parameters ().size > 0) {
// declare construction parameter array
var cparamsinit = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
cparamsinit.add_argument (new CCodeIdentifier ("GParameter"));
- cparamsinit.add_argument (new CCodeConstant ((n_params + 3 * current_class.get_type_parameters ().size).to_string ()));
+ cparamsinit.add_argument (new CCodeConstant ((current_class.get_type_parameters ().size).to_string ()));
var cdecl = new CCodeDeclaration ("GParameter *");
cdecl.add_declarator (new CCodeVariableDeclarator ("__params", cparamsinit));
cinit.append (cdeclaration);
if (!((CreationMethod) m).chain_up) {
- // TODO implicitly chain up to base class as in add_object_creation
+ // TODO implicitly chain up to base class as in prepend_object_creation
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_create_instance"));
ccall.add_argument (new CCodeIdentifier ("object_type"));
cdecl.initializer = new CCodeCastExpression (ccall, cl.get_cname () + "*");
cinit.append (cdeclaration);
if (!((CreationMethod) m).chain_up) {
- // TODO implicitly chain up to base class as in add_object_creation
+ // TODO implicitly chain up to base class as in prepend_object_creation
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0"));
ccall.add_argument (new CCodeIdentifier (cl.get_cname ()));
cdecl.initializer = ccall;
return null;
}
- private void add_object_creation (CCodeBlock b, bool has_params) {
+ private void prepend_object_creation (CCodeBlock b, bool has_params) {
var cl = (Class) current_type_symbol;
if (!has_params && cl.base_class != gobject_type) {
var cdeclaration = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
cdeclaration.add_declarator (cdecl);
- b.add_statement (cdeclaration);
+ b.prepend_statement (cdeclaration);
}
public override void visit_creation_method (CreationMethod m) {
}
if (current_type_symbol is Class && gobject_type != null && current_class.is_subtype_of (gobject_type)
- && (((CreationMethod) m).n_construction_params > 0 || current_class.get_type_parameters ().size > 0)
+ && current_class.get_type_parameters ().size > 0
&& !((CreationMethod) m).chain_up) {
var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.GREATER_THAN, new CCodeIdentifier ("__params_it"), new CCodeIdentifier ("__params"));
var cdofreeparam = new CCodeBlock ();
/* valacreationmethod.vala
*
- * Copyright (C) 2007-2009 Jürg Billeter
+ * Copyright (C) 2007-2010 Jürg Billeter
* Copyright (C) 2007-2008 Raffaele Sandrini
*
* This library is free software; you can redistribute it and/or
*/
public string class_name { get; set; }
- /**
- * Specifies the number of parameters this creation method sets.
- */
- public int n_construction_params { get; set; }
-
/**
* Specifies a custom C return type for that creation method.
* Only the idl parser and the interface writer should use this.
var cl = parent_symbol as Class;
- // count construction property assignments
- if (analyzer.context.profile == Profile.GOBJECT && cl != null
- && cl.is_subtype_of (analyzer.object_type)) {
- int n_params = 0;
- foreach (Statement stmt in body.get_statements ()) {
- var expr_stmt = stmt as ExpressionStatement;
- if (expr_stmt != null) {
- Property prop = expr_stmt.assigned_property ();
- if (prop != null && prop.set_accessor.construction) {
- n_params++;
- }
- }
- }
- n_construction_params = n_params;
- }
-
// ensure we chain up to base constructor
if (!chain_up && cl != null && cl.base_class != null) {
if (analyzer.context.profile == Profile.GOBJECT
&& 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.is_subtype_of (analyzer.object_type)
- && (n_construction_params > 0 || cl.constructor != null)) {
- // no chain up when using GObject construct properties or constructor
} else if (cl.base_class.default_construction_method == null
|| cl.base_class.default_construction_method.access == SymbolAccessibility.PRIVATE) {
if (analyzer.context.profile == Profile.GOBJECT) {