+2007-07-23 Jürg Billeter <j@bitron.ch>
+
+ * vala/valaexpressionstatement.vala, vala/valasemanticanalyzer.vala,
+ gobject/valacodegeneratorassignment.vala,
+ gobject/valacodegeneratorclass.vala,
+ gobject/valacodegeneratormethod.vala: use setters for non-construction
+ properties in creation methods to improve performance
+
2007-07-23 Jürg Billeter <j@bitron.ch>
* vala/valainterfacewriter.vala: another fix for libraries with generic
MemberAccess ma = null;
if (a.left is MemberAccess) {
- ma = (MemberAccess)a.left;
+ ma = (MemberAccess) a.left;
}
if (a.left.symbol_reference is Property) {
var prop = (Property) a.left.symbol_reference;
- if (current_type_symbol is Class && ma.inner == null && in_creation_method) {
+ if (prop.set_accessor.construction && current_type_symbol is Class && ma.inner == null && in_creation_method) {
// this property is used as a construction parameter
var cpointer = new CCodeIdentifier ("__params_it");
var ccall = get_property_set_call (prop, ma, cexpr);
- // assignments are expressions, so return the current property value
- var ccomma = new CCodeCommaExpression ();
- ccomma.append_expression (ccall); // update property
- ccomma.append_expression ((CCodeExpression) ma.ccodenode); // current property value
-
- a.ccodenode = ccomma;
+ // assignments are expressions, so return the current property value, except if we're sure that it can't be used
+ if (!(a.parent_node is ExpressionStatement)) {
+ var ccomma = new CCodeCommaExpression ();
+ ccomma.append_expression (ccall); // update property
+ ccomma.append_expression ((CCodeExpression) ma.ccodenode); // current property value
+
+ a.ccodenode = ccomma;
+ } else {
+ a.ccodenode = ccall;
+ }
}
} else if (a.left.symbol_reference is Signal) {
var sig = (Signal) a.left.symbol_reference;
cspec.add_argument (func_name_constant);
cspec.add_argument (new CCodeConstant ("\"destroy func\""));
cspec.add_argument (new CCodeConstant ("\"destroy func\""));
- cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY"));
+ cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE"));
cinst.add_argument (cspec);
init_block.add_statement (new CCodeExpressionStatement (cinst));
prop_enum.add_value (enum_value, null);
if (m is CreationMethod) {
if (current_type_symbol is Class && m.body != null) {
- add_object_creation ((CCodeBlock) m.body.ccodenode);
+ var cblock = new CCodeBlock ();
+
+ foreach (CodeNode stmt in m.body.get_statements ()) {
+ if (((ExpressionStatement) stmt).assigned_property ().set_accessor.construction) {
+ if (stmt.ccodenode is CCodeFragment) {
+ foreach (CCodeStatement cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
+ cblock.add_statement (cstmt);
+ }
+ } else {
+ cblock.add_statement ((CCodeStatement) stmt.ccodenode);
+ }
+ }
+ }
+
+ add_object_creation (cblock);
+
+ foreach (CodeNode stmt in m.body.get_statements ()) {
+ if (!((ExpressionStatement) stmt).assigned_property ().set_accessor.construction) {
+ if (stmt.ccodenode is CCodeFragment) {
+ foreach (CCodeStatement cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
+ cblock.add_statement (cstmt);
+ }
+ } else {
+ cblock.add_statement ((CCodeStatement) stmt.ccodenode);
+ }
+ }
+ }
+
+ m.body.ccodenode = cblock;
}
in_creation_method = false;
/* destroy func properties for generic types */
foreach (TypeParameter type_param in current_class.get_type_parameters ()) {
string func_name = "%s_destroy_func".printf (type_param.name.down ());
- var func_name_constant = new CCodeConstant ("\"%s-destroy-func\"".printf (type_param.name.down ()));
-
- // this property is used as a construction parameter
- var cpointer = new CCodeIdentifier ("__params_it");
-
- var ccomma = new CCodeCommaExpression ();
- // set name in array for current parameter
- var cnamemember = new CCodeMemberAccess.pointer (cpointer, "name");
- ccomma.append_expression (new CCodeAssignment (cnamemember, func_name_constant));
- var gvaluearg = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeMemberAccess.pointer (cpointer, "value"));
-
- // initialize GValue in array for current parameter
- var cvalueinit = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
- cvalueinit.add_argument (gvaluearg);
- cvalueinit.add_argument (new CCodeIdentifier ("G_TYPE_POINTER"));
- ccomma.append_expression (cvalueinit);
-
- // set GValue for current parameter
- var cvalueset = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_pointer"));
- cvalueset.add_argument (gvaluearg);
- cvalueset.add_argument (new CCodeIdentifier (func_name));
- ccomma.append_expression (cvalueset);
-
- // move pointer to next parameter in array
- ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, cpointer));
-
- cinit.append (new CCodeExpressionStatement (ccomma));
+ var cmember = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name);
+ var cassign = new CCodeAssignment (cmember, new CCodeIdentifier (func_name));
+ function.block.add_statement (new CCodeExpressionStatement (cassign));
}
} else {
var st = (Struct) m.parent_symbol;
}
/**
- * Returns whether this statement sets a property.
+ * Returns the property this statement sets, if any.
*
- * @return true if this statement sets a property, false otherwise
+ * @return the property this statement sets, or null if it doesn't set
+ * a property
*/
- public bool sets_property () {
+ public Property assigned_property () {
if (expression is Assignment) {
var assign = (Assignment) expression;
if (assign.left is MemberAccess) {
var ma = (MemberAccess) assign.left;
- return (ma.symbol_reference is Property);
+ if (ma.symbol_reference is Property) {
+ return (Property) ma.symbol_reference;
+ }
}
}
- return false;
+ return null;
}
}
if (m.body != null && current_class != null) {
int n_params = 0;
foreach (Statement stmt in m.body.get_statements ()) {
- if (!(stmt is ExpressionStatement) || !((ExpressionStatement) stmt).sets_property ()) {
+ if (!(stmt is ExpressionStatement) || ((ExpressionStatement) stmt).assigned_property () == null) {
m.error = true;
Report.error (stmt.source_reference, "class creation methods only allow property assignment statements");
return;
}
- n_params++;
+ if (((ExpressionStatement) stmt).assigned_property ().set_accessor.construction) {
+ n_params++;
+ }
}
m.n_construction_params = n_params;
}