add CCodeExpressionBinding and CCodeAssignmentBinding classes and move
authorJuerg Billeter <j@bitron.ch>
Thu, 27 Sep 2007 11:59:26 +0000 (11:59 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Thu, 27 Sep 2007 11:59:26 +0000 (11:59 +0000)
2007-09-27  Juerg Billeter  <j@bitron.ch>

* vala/valacodebinding.vala, vala/valasemanticanalyzer.vala,
  gobject/Makefile.am, gobject/valaccodeassignmentbinding.vala,
  gobject/valaccodeexpressionbinding.vala,
  gobject/valaccodegenerator.vala,
  gobject/valaccodegeneratorassignment.vala,
  gobject/valaccodegeneratorclass.vala,
  gobject/valaccodegeneratorsignal.vala: add CCodeExpressionBinding and
  CCodeAssignmentBinding classes and move relevant code from
  CCodeGenerator to CCodeAssignmentBinding

svn path=/trunk/; revision=631

ChangeLog
gobject/Makefile.am
gobject/valaccodeassignmentbinding.vala [moved from gobject/valaccodegeneratorassignment.vala with 59% similarity]
gobject/valaccodeexpressionbinding.vala [new file with mode: 0644]
gobject/valaccodegenerator.vala
gobject/valaccodegeneratorclass.vala
gobject/valaccodegeneratorsignal.vala
vala/valacodebinding.vala
vala/valasemanticanalyzer.vala

index 2b2f4f8..592b4d6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2007-09-27  Jürg Billeter  <j@bitron.ch>
+
+       * vala/valacodebinding.vala, vala/valasemanticanalyzer.vala,
+         gobject/Makefile.am, gobject/valaccodeassignmentbinding.vala,
+         gobject/valaccodeexpressionbinding.vala,
+         gobject/valaccodegenerator.vala,
+         gobject/valaccodegeneratorassignment.vala,
+         gobject/valaccodegeneratorclass.vala,
+         gobject/valaccodegeneratorsignal.vala: add CCodeExpressionBinding and
+         CCodeAssignmentBinding classes and move relevant code from
+         CCodeGenerator to CCodeAssignmentBinding
+
 2007-09-26  Jürg Billeter  <j@bitron.ch>
 
        * vapigen/valagidlparser.vala: support # comment lines in .metadata
index fe6f7d4..b2bb168 100644 (file)
@@ -13,18 +13,21 @@ lib_LTLIBRARIES = \
 
 libvala_la_SOURCES = \
        gobject.vala.stamp \
+       valaccodeassignmentbinding.c \
+       valaccodeassignmentbinding.h \
+       valaccodeassignmentbinding.vala \
        valaccodebinding.c \
        valaccodebinding.h \
        valaccodebinding.vala \
        valaccodecompiler.c \
        valaccodecompiler.h \
        valaccodecompiler.vala \
+       valaccodeexpressionbinding.c \
+       valaccodeexpressionbinding.h \
+       valaccodeexpressionbinding.vala \
        valaccodegenerator.c \
        valaccodegenerator.h \
        valaccodegenerator.vala \
-       valaccodegeneratorassignment.c \
-       valaccodegeneratorassignment.h \
-       valaccodegeneratorassignment.vala \
        valaccodegeneratorclass.c \
        valaccodegeneratorclass.h \
        valaccodegeneratorclass.vala \
@@ -72,10 +75,11 @@ libvala_la_SOURCES = \
 gobjectincludedir = $(includedir)/vala-1.0/gobject
 
 gobjectinclude_HEADERS = \
+       valaccodeassignmentbinding.h \
        valaccodebinding.h \
        valaccodecompiler.h \
+       valaccodeexpressionbinding.h \
        valaccodegenerator.h \
-       valaccodegeneratorassignment.h \
        valaccodegeneratorclass.h \
        valaccodegeneratorinterface.h \
        valaccodegeneratorinvocationexpression.h \
similarity index 59%
rename from gobject/valaccodegeneratorassignment.vala
rename to gobject/valaccodeassignmentbinding.vala
index 4e2aac9..2249438 100644 (file)
@@ -1,4 +1,4 @@
-/* valaccodegeneratorassignment.vala
+/* valaccodeassignmentbinding.vala
  *
  * Copyright (C) 2006-2007  Jürg Billeter, Raffaele Sandrini
  *
  *
  * Author:
  *     Jürg Billeter <j@bitron.ch>
- *     Raffaele Sandrini <rasa@gmx.ch>
+ *     Raffaele Sandrini <raffaele@sandrini.ch>
  */
 
 using GLib;
 using Gee;
 
-public class Vala.CCodeGenerator {
-       public override void visit_assignment (Assignment! a) {
-               a.accept_children (this);
+/**
+ * The link between an assignment and generated code.
+ */
+public class Vala.CCodeAssignmentBinding : CCodeExpressionBinding {
+       public Assignment! assignment { get; set; }
 
-               MemberAccess ma = null;
-               
-               if (a.left is MemberAccess) {
-                       ma = (MemberAccess) a.left;
-               }
+       public CCodeAssignmentBinding (construct CodeGenerator! codegen, construct Assignment! assignment) {
+       }
+
+       public override void emit () {
+               assignment.accept_children (codegen);
+
+               MemberAccess ma = assignment.left as MemberAccess;
 
-               if (a.left.symbol_reference is Property) {
-                       var prop = (Property) a.left.symbol_reference;
+               if (assignment.left.symbol_reference is Property) {
+                       var prop = (Property) assignment.left.symbol_reference;
                        
-                       if (prop.set_accessor.construction && current_type_symbol is Class && in_creation_method) {
+                       if (prop.set_accessor.construction && codegen.current_type_symbol is Class && codegen.in_creation_method) {
                                // this property is used as a construction parameter
                                var cpointer = new CCodeIdentifier ("__params_it");
                                
@@ -56,70 +60,70 @@ public class Vala.CCodeGenerator {
                                ccomma.append_expression (cvalueinit);
                                
                                // set GValue for current parameter
-                               var cvalueset = new CCodeFunctionCall (get_value_setter_function (prop.type_reference));
+                               var cvalueset = new CCodeFunctionCall (codegen.get_value_setter_function (prop.type_reference));
                                cvalueset.add_argument (gvaluearg);
-                               cvalueset.add_argument ((CCodeExpression) a.right.ccodenode);
+                               cvalueset.add_argument ((CCodeExpression) assignment.right.ccodenode);
                                ccomma.append_expression (cvalueset);
                                
                                // move pointer to next parameter in array
                                ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, cpointer));
                                
-                               a.ccodenode = ccomma;
+                               codenode = ccomma;
                        } else {
-                               CCodeExpression cexpr = (CCodeExpression) a.right.ccodenode;
+                               CCodeExpression cexpr = (CCodeExpression) assignment.right.ccodenode;
 
                                if (!prop.no_accessor_method) {
-                                       cexpr = get_implicit_cast_expression (cexpr, a.right.static_type, prop.type_reference);
+                                       cexpr = codegen.get_implicit_cast_expression (cexpr, assignment.right.static_type, prop.type_reference);
                                }
 
-                               if (a.operator != AssignmentOperator.SIMPLE) {
+                               if (assignment.operator != AssignmentOperator.SIMPLE) {
                                        CCodeBinaryOperator cop;
-                                       if (a.operator == AssignmentOperator.BITWISE_OR) {
+                                       if (assignment.operator == AssignmentOperator.BITWISE_OR) {
                                                cop = CCodeBinaryOperator.BITWISE_OR;
-                                       } else if (a.operator == AssignmentOperator.BITWISE_AND) {
+                                       } else if (assignment.operator == AssignmentOperator.BITWISE_AND) {
                                                cop = CCodeBinaryOperator.BITWISE_AND;
-                                       } else if (a.operator == AssignmentOperator.BITWISE_XOR) {
+                                       } else if (assignment.operator == AssignmentOperator.BITWISE_XOR) {
                                                cop = CCodeBinaryOperator.BITWISE_XOR;
-                                       } else if (a.operator == AssignmentOperator.ADD) {
+                                       } else if (assignment.operator == AssignmentOperator.ADD) {
                                                cop = CCodeBinaryOperator.PLUS;
-                                       } else if (a.operator == AssignmentOperator.SUB) {
+                                       } else if (assignment.operator == AssignmentOperator.SUB) {
                                                cop = CCodeBinaryOperator.MINUS;
-                                       } else if (a.operator == AssignmentOperator.MUL) {
+                                       } else if (assignment.operator == AssignmentOperator.MUL) {
                                                cop = CCodeBinaryOperator.MUL;
-                                       } else if (a.operator == AssignmentOperator.DIV) {
+                                       } else if (assignment.operator == AssignmentOperator.DIV) {
                                                cop = CCodeBinaryOperator.DIV;
-                                       } else if (a.operator == AssignmentOperator.PERCENT) {
+                                       } else if (assignment.operator == AssignmentOperator.PERCENT) {
                                                cop = CCodeBinaryOperator.MOD;
-                                       } else if (a.operator == AssignmentOperator.SHIFT_LEFT) {
+                                       } else if (assignment.operator == AssignmentOperator.SHIFT_LEFT) {
                                                cop = CCodeBinaryOperator.SHIFT_LEFT;
-                                       } else if (a.operator == AssignmentOperator.SHIFT_RIGHT) {
+                                       } else if (assignment.operator == AssignmentOperator.SHIFT_RIGHT) {
                                                cop = CCodeBinaryOperator.SHIFT_RIGHT;
                                        }
-                                       cexpr = new CCodeBinaryExpression (cop, (CCodeExpression) a.left.ccodenode, new CCodeParenthesizedExpression (cexpr));
+                                       cexpr = new CCodeBinaryExpression (cop, (CCodeExpression) assignment.left.ccodenode, new CCodeParenthesizedExpression (cexpr));
                                }
                                
-                               var ccall = get_property_set_call (prop, ma, cexpr);
+                               var ccall = codegen.get_property_set_call (prop, ma, cexpr);
                                
                                // 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)) {
+                               if (!(assignment.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;
+                                       codenode = ccomma;
                                } else {
-                                       a.ccodenode = ccall;
+                                       codenode = ccall;
                                }
                        }
-               } else if (a.left.symbol_reference is Signal) {
-                       var sig = (Signal) a.left.symbol_reference;
+               } else if (assignment.left.symbol_reference is Signal) {
+                       var sig = (Signal) assignment.left.symbol_reference;
                        
-                       var m = (Method) a.right.symbol_reference;
+                       var m = (Method) assignment.right.symbol_reference;
 
                        string connect_func;
                        bool disconnect = false;
 
-                       if (a.operator == AssignmentOperator.ADD) {
+                       if (assignment.operator == AssignmentOperator.ADD) {
                                if (sig is DBusSignal) {
                                        connect_func = "dbus_g_proxy_connect_signal";
                                } else {
@@ -128,7 +132,7 @@ public class Vala.CCodeGenerator {
                                                connect_func = "g_signal_connect";
                                        }
                                }
-                       } else if (a.operator == AssignmentOperator.SUB) {
+                       } else if (assignment.operator == AssignmentOperator.SUB) {
                                if (sig is DBusSignal) {
                                        connect_func = "dbus_g_proxy_disconnect_signal";
                                } else {
@@ -136,8 +140,8 @@ public class Vala.CCodeGenerator {
                                }
                                disconnect = true;
                        } else {
-                               a.error = true;
-                               Report.error (a.source_reference, "Specified compound assignment type for signals not supported.");
+                               assignment.error = true;
+                               Report.error (assignment.source_reference, "Specified compound assignment type for signals not supported.");
                                return;
                        }
 
@@ -156,8 +160,8 @@ public class Vala.CCodeGenerator {
                                
                                // get signal id
                                var ccomma = new CCodeCommaExpression ();
-                               var temp_decl = get_temp_variable_declarator (uint_type);
-                               temp_vars.insert (0, temp_decl);
+                               var temp_decl = codegen.get_temp_variable_declarator (codegen.uint_type);
+                               codegen.temp_vars.insert (0, temp_decl);
                                var parse_call = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_parse_name"));
                                parse_call.add_argument (sig.get_canonical_cconstant ());
                                var decl_type = (DataType) sig.parent_symbol;
@@ -177,14 +181,14 @@ public class Vala.CCodeGenerator {
                        ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier (m.get_cname ()), "GCallback"));
 
                        if (m.instance) {
-                               if (a.right is MemberAccess) {
-                                       var right_ma = (MemberAccess) a.right;
+                               if (assignment.right is MemberAccess) {
+                                       var right_ma = (MemberAccess) assignment.right;
                                        if (right_ma.inner != null) {
                                                ccall.add_argument ((CCodeExpression) right_ma.inner.ccodenode);
                                        } else {
                                                ccall.add_argument (new CCodeIdentifier ("self"));
                                        }
-                               } else if (a.right is LambdaExpression) {
+                               } else if (assignment.right is LambdaExpression) {
                                        ccall.add_argument (new CCodeIdentifier ("self"));
                                }
                                if (!disconnect) {
@@ -200,7 +204,7 @@ public class Vala.CCodeGenerator {
                                ccall.add_argument (new CCodeConstant ("NULL"));
                        }
                        
-                       a.ccodenode = ccall;
+                       codenode = ccall;
                        
                        if (sig is DBusSignal && !disconnect) {
                                bool first = true;
@@ -213,11 +217,11 @@ public class Vala.CCodeGenerator {
                                        sig.add_parameter (param);
                                }
 
-                               sig.accept (this);
+                               sig.accept (codegen);
 
                                // FIXME should only be done once per marshaller
                                var register_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_object_register_marshaller"));
-                               register_call.add_argument (new CCodeIdentifier (get_signal_marshaller_function (sig)));
+                               register_call.add_argument (new CCodeIdentifier (codegen.get_signal_marshaller_function (sig)));
                                register_call.add_argument (new CCodeIdentifier ("G_TYPE_NONE"));
 
                                var add_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_add_signal"));
@@ -235,7 +239,7 @@ public class Vala.CCodeGenerator {
                                                first = false;
                                                continue;
                                        }
-                                       if (param.type_reference.data_type is Array && ((Array) param.type_reference.data_type).element_type != string_type.data_type) {
+                                       if (param.type_reference.data_type is Array && ((Array) param.type_reference.data_type).element_type != codegen.string_type.data_type) {
                                                var array = (Array) param.type_reference.data_type;
                                                var carray_type = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_type_get_collection"));
                                                carray_type.add_argument (new CCodeConstant ("\"GArray\""));
@@ -254,15 +258,15 @@ public class Vala.CCodeGenerator {
                                ccomma.append_expression (register_call);
                                ccomma.append_expression (add_call);
                                ccomma.append_expression (ccall);
-                               a.ccodenode = ccomma;
+                               codenode = ccomma;
                        }
-               } else if (a.left is ElementAccess && !(((ElementAccess) a.left).container.static_type.data_type is Array)) {
+               } else if (assignment.left is ElementAccess && !(((ElementAccess) assignment.left).container.static_type.data_type is Array)) {
                        // custom element access
-                       CCodeExpression rhs = (CCodeExpression) a.right.ccodenode;
+                       CCodeExpression rhs = (CCodeExpression) assignment.right.ccodenode;
 
-                       rhs = get_implicit_cast_expression (rhs, a.right.static_type, a.left.static_type);
+                       rhs = codegen.get_implicit_cast_expression (rhs, assignment.right.static_type, assignment.left.static_type);
 
-                       var expr = (ElementAccess) a.left;
+                       var expr = (ElementAccess) assignment.left;
                        var container_type = expr.container.static_type.data_type;
                        Collection<Expression> indices = expr.get_indices ();
                        Iterator<Expression> indices_it = indices.iterator ();
@@ -271,8 +275,8 @@ public class Vala.CCodeGenerator {
                        var ccontainer = (CCodeExpression) expr.container.ccodenode;
                        var cindex = (CCodeExpression) indices_it.get ().ccodenode;
 
-                       if (container_type != null && list_type != null && map_type != null &&
-                           (container_type.is_subtype_of (list_type) || container_type.is_subtype_of (map_type))) {
+                       if (container_type != null && codegen.list_type != null && codegen.map_type != null &&
+                           (container_type.is_subtype_of (codegen.list_type) || container_type.is_subtype_of (codegen.map_type))) {
                                var set_method = (Method) container_type.scope.lookup ("set");
                                Collection<FormalParameter> set_params = set_method.get_parameters ();
                                Iterator<FormalParameter> set_params_it = set_params.iterator ();
@@ -280,47 +284,47 @@ public class Vala.CCodeGenerator {
                                var set_param = set_params_it.get ();
 
                                if (set_param.type_reference.type_parameter != null) {
-                                       var index_type = SemanticAnalyzer.get_actual_type (expr.container.static_type, set_method, set_param.type_reference, a);
-                                       cindex = convert_to_generic_pointer (cindex, index_type);
+                                       var index_type = SemanticAnalyzer.get_actual_type (expr.container.static_type, set_method, set_param.type_reference, assignment);
+                                       cindex = codegen.convert_to_generic_pointer (cindex, index_type);
                                }
 
                                var set_ccall = new CCodeFunctionCall (new CCodeIdentifier (set_method.get_cname ()));
                                set_ccall.add_argument (new CCodeCastExpression (ccontainer, container_type.get_cname () + "*"));
                                set_ccall.add_argument (cindex);
-                               set_ccall.add_argument (convert_to_generic_pointer (rhs, expr.static_type));
+                               set_ccall.add_argument (codegen.convert_to_generic_pointer (rhs, expr.static_type));
 
-                               a.ccodenode = set_ccall;
+                               codenode = set_ccall;
                        } else {
-                               Report.error (a.source_reference, "internal error: unsupported element access");
-                               a.error = true;
+                               Report.error (assignment.source_reference, "internal error: unsupported element access");
+                               assignment.error = true;
                        }
                } else {
-                       CCodeExpression rhs = (CCodeExpression) a.right.ccodenode;
+                       CCodeExpression rhs = (CCodeExpression) assignment.right.ccodenode;
 
-                       rhs = get_implicit_cast_expression (rhs, a.right.static_type, a.left.static_type);
+                       rhs = codegen.get_implicit_cast_expression (rhs, assignment.right.static_type, assignment.left.static_type);
 
-                       bool unref_old = (memory_management && a.left.static_type.takes_ownership);
+                       bool unref_old = (codegen.memory_management && assignment.left.static_type.takes_ownership);
                        bool array = false;
-                       if (a.left.static_type.data_type is Array) {
-                               array = !(get_array_length_cexpression (a.left, 1) is CCodeConstant);
+                       if (assignment.left.static_type.data_type is Array) {
+                               array = !(codegen.get_array_length_cexpression (assignment.left, 1) is CCodeConstant);
                        }
                        
                        if (unref_old || array) {
                                var ccomma = new CCodeCommaExpression ();
                                
-                               var temp_decl = get_temp_variable_declarator (a.left.static_type);
-                               temp_vars.insert (0, temp_decl);
+                               var temp_decl = codegen.get_temp_variable_declarator (assignment.left.static_type);
+                               codegen.temp_vars.insert (0, temp_decl);
                                ccomma.append_expression (new CCodeAssignment (new CCodeIdentifier (temp_decl.name), rhs));
                                if (unref_old) {
                                        /* unref old value */
-                                       ccomma.append_expression (get_unref_expression ((CCodeExpression) a.left.ccodenode, a.left.static_type, a.left));
+                                       ccomma.append_expression (codegen.get_unref_expression ((CCodeExpression) assignment.left.ccodenode, assignment.left.static_type, assignment.left));
                                }
                                
                                if (array) {
-                                       var arr = (Array) a.left.static_type.data_type;
+                                       var arr = (Array) assignment.left.static_type.data_type;
                                        for (int dim = 1; dim <= arr.rank; dim++) {
-                                               var lhs_array_len = get_array_length_cexpression (a.left, dim);
-                                               var rhs_array_len = get_array_length_cexpression (a.right, dim);
+                                               var lhs_array_len = codegen.get_array_length_cexpression (assignment.left, dim);
+                                               var rhs_array_len = codegen.get_array_length_cexpression (assignment.right, dim);
                                                ccomma.append_expression (new CCodeAssignment (lhs_array_len, rhs_array_len));
                                        }
                                }
@@ -331,98 +335,49 @@ public class Vala.CCodeGenerator {
                        }
                        
                        var cop = CCodeAssignmentOperator.SIMPLE;
-                       if (a.operator == AssignmentOperator.BITWISE_OR) {
+                       if (assignment.operator == AssignmentOperator.BITWISE_OR) {
                                cop = CCodeAssignmentOperator.BITWISE_OR;
-                       } else if (a.operator == AssignmentOperator.BITWISE_AND) {
+                       } else if (assignment.operator == AssignmentOperator.BITWISE_AND) {
                                cop = CCodeAssignmentOperator.BITWISE_AND;
-                       } else if (a.operator == AssignmentOperator.BITWISE_XOR) {
+                       } else if (assignment.operator == AssignmentOperator.BITWISE_XOR) {
                                cop = CCodeAssignmentOperator.BITWISE_XOR;
-                       } else if (a.operator == AssignmentOperator.ADD) {
+                       } else if (assignment.operator == AssignmentOperator.ADD) {
                                cop = CCodeAssignmentOperator.ADD;
-                       } else if (a.operator == AssignmentOperator.SUB) {
+                       } else if (assignment.operator == AssignmentOperator.SUB) {
                                cop = CCodeAssignmentOperator.SUB;
-                       } else if (a.operator == AssignmentOperator.MUL) {
+                       } else if (assignment.operator == AssignmentOperator.MUL) {
                                cop = CCodeAssignmentOperator.MUL;
-                       } else if (a.operator == AssignmentOperator.DIV) {
+                       } else if (assignment.operator == AssignmentOperator.DIV) {
                                cop = CCodeAssignmentOperator.DIV;
-                       } else if (a.operator == AssignmentOperator.PERCENT) {
+                       } else if (assignment.operator == AssignmentOperator.PERCENT) {
                                cop = CCodeAssignmentOperator.PERCENT;
-                       } else if (a.operator == AssignmentOperator.SHIFT_LEFT) {
+                       } else if (assignment.operator == AssignmentOperator.SHIFT_LEFT) {
                                cop = CCodeAssignmentOperator.SHIFT_LEFT;
-                       } else if (a.operator == AssignmentOperator.SHIFT_RIGHT) {
+                       } else if (assignment.operator == AssignmentOperator.SHIFT_RIGHT) {
                                cop = CCodeAssignmentOperator.SHIFT_RIGHT;
                        }
                
-                       a.ccodenode = new CCodeAssignment ((CCodeExpression) a.left.ccodenode, rhs, cop);
+                       codenode = new CCodeAssignment ((CCodeExpression) assignment.left.ccodenode, rhs, cop);
 
-                       if (unref_old && a.left.ccodenode is CCodeElementAccess) {
+                       if (unref_old && assignment.left.ccodenode is CCodeElementAccess) {
                                // ensure that index expression in element access doesn't get evaluated more than once
                                // except when it's a simple expression
-                               var cea = (CCodeElementAccess) a.left.ccodenode;
+                               var cea = (CCodeElementAccess) assignment.left.ccodenode;
                                if (!(cea.index is CCodeConstant || cea.index is CCodeIdentifier)) {
-                                       var index_temp_decl = get_temp_variable_declarator (int_type);
-                                       temp_vars.insert (0, index_temp_decl);
+                                       var index_temp_decl = codegen.get_temp_variable_declarator (codegen.int_type);
+                                       codegen.temp_vars.insert (0, index_temp_decl);
                                        
                                        var ccomma = new CCodeCommaExpression ();
                                        ccomma.append_expression (new CCodeAssignment (new CCodeIdentifier (index_temp_decl.name), cea.index));
-                                       ccomma.append_expression ((CCodeExpression) a.ccodenode);
+                                       ccomma.append_expression (codenode);
 
                                        cea.index = new CCodeIdentifier (index_temp_decl.name);
                                        
-                                       a.ccodenode = ccomma;
+                                       codenode = ccomma;
                                }
                        }
                }
-       }
-
-       private CCodeFunctionCall get_property_set_call (Property! prop, MemberAccess! ma, CCodeExpression! cexpr) {
-               var cl = (Class) prop.parent_symbol;
-               var set_func = "g_object_set";
-               
-               var base_property = prop;
-               if (!prop.no_accessor_method) {
-                       if (prop.base_property != null) {
-                               base_property = prop.base_property;
-                       } else if (prop.base_interface_property != null) {
-                               base_property = prop.base_interface_property;
-                       }
-                       var base_property_type = (DataType) base_property.parent_symbol;
-                       set_func = "%s_set_%s".printf (base_property_type.get_lower_case_cname (null), base_property.name);
-               }
-               
-               var ccall = new CCodeFunctionCall (new CCodeIdentifier (set_func));
-
-               /* target instance is first argument */
-               CCodeExpression instance;
-
-               TypeReference instance_expression_type;
-               if (ma.inner == null) {
-                       instance = new CCodeIdentifier ("self");
-                       instance_expression_type = new TypeReference ();
-                       instance_expression_type.data_type = current_type_symbol;
-               } else {
-                       instance = (CCodeExpression) ma.inner.ccodenode;
-                       instance_expression_type = ma.inner.static_type;
-               }
-
-               var instance_target_type = new TypeReference ();
-               instance_target_type.data_type = (DataType) base_property.parent_symbol;
-               instance = get_implicit_cast_expression (instance, instance_expression_type, instance_target_type);
-
-               ccall.add_argument (instance);
-
-               if (prop.no_accessor_method) {
-                       /* property name is second argument of g_object_set */
-                       ccall.add_argument (prop.get_canonical_cconstant ());
-               }
-                       
-               ccall.add_argument (cexpr);
-               
-               if (prop.no_accessor_method) {
-                       ccall.add_argument (new CCodeConstant ("NULL"));
-               }
 
-               return ccall;
+               assignment.ccodenode = codenode;
        }
 }
-
diff --git a/gobject/valaccodeexpressionbinding.vala b/gobject/valaccodeexpressionbinding.vala
new file mode 100644 (file)
index 0000000..bb2c5c4
--- /dev/null
@@ -0,0 +1,30 @@
+/* valaccodeexpressionbinding.vala
+ *
+ * Copyright (C) 2007  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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Jürg Billeter <j@bitron.ch>
+ */
+
+using GLib;
+
+/**
+ * The link between an expression and generated code.
+ */
+public abstract class Vala.CCodeExpressionBinding : CCodeBinding {
+       public CCodeExpression codenode { get; set; }
+}
index b3f8b35..18182d4 100644 (file)
@@ -37,7 +37,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
        
        Symbol root_symbol;
        Symbol current_symbol;
-       Symbol current_type_symbol;
+       public Symbol current_type_symbol;
        Class current_class;
        Method current_method;
        TypeReference current_return_type;
@@ -67,7 +67,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
        CCodeBlock block;
        
        /* all temporary variables */
-       ArrayList<VariableDeclarator> temp_vars = new ArrayList<VariableDeclarator> ();
+       public ArrayList<VariableDeclarator> temp_vars = new ArrayList<VariableDeclarator> ();
        /* temporary variables that own their content */
        ArrayList<VariableDeclarator> temp_ref_vars = new ArrayList<VariableDeclarator> ();
        /* cache to check whether a certain marshaller has been created yet */
@@ -80,38 +80,38 @@ public class Vala.CCodeGenerator : CodeGenerator {
        private int next_temp_var_id = 0;
        private int current_try_id = 0;
        private int next_try_id = 0;
-       private bool in_creation_method = false;
+       public bool in_creation_method = false;
        private bool current_method_inner_error = false;
 
-       TypeReference bool_type;
-       TypeReference char_type;
-       TypeReference unichar_type;
-       TypeReference short_type;
-       TypeReference ushort_type;
-       TypeReference int_type;
-       TypeReference uint_type;
-       TypeReference long_type;
-       TypeReference ulong_type;
-       TypeReference int64_type;
-       TypeReference uint64_type;
-       TypeReference string_type;
-       TypeReference float_type;
-       TypeReference double_type;
-       DataType gtypeinstance_type;
-       DataType gobject_type;
-       DataType gerror_type;
-       DataType glist_type;
-       DataType gslist_type;
-       DataType gstring_type;
-       DataType garray_type;
-       TypeReference gquark_type;
-       TypeReference mutex_type;
-       DataType type_module_type;
-       DataType iterable_type;
-       DataType iterator_type;
-       DataType list_type;
-       DataType map_type;
-       DataType connection_type;
+       public TypeReference bool_type;
+       public TypeReference char_type;
+       public TypeReference unichar_type;
+       public TypeReference short_type;
+       public TypeReference ushort_type;
+       public TypeReference int_type;
+       public TypeReference uint_type;
+       public TypeReference long_type;
+       public TypeReference ulong_type;
+       public TypeReference int64_type;
+       public TypeReference uint64_type;
+       public TypeReference string_type;
+       public TypeReference float_type;
+       public TypeReference double_type;
+       public DataType gtypeinstance_type;
+       public DataType gobject_type;
+       public DataType gerror_type;
+       public DataType glist_type;
+       public DataType gslist_type;
+       public DataType gstring_type;
+       public DataType garray_type;
+       public TypeReference gquark_type;
+       public TypeReference mutex_type;
+       public DataType type_module_type;
+       public DataType iterable_type;
+       public DataType iterator_type;
+       public DataType list_type;
+       public DataType map_type;
+       public DataType connection_type;
 
        Method substring_method;
 
@@ -918,7 +918,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                }
        }
 
-       private VariableDeclarator get_temp_variable_declarator (TypeReference! type, bool takes_ownership = true, CodeNode node_reference = null) {
+       public VariableDeclarator get_temp_variable_declarator (TypeReference! type, bool takes_ownership = true, CodeNode node_reference = null) {
                var decl = new VariableDeclarator ("_tmp%d".printf (next_temp_var_id));
                decl.type_reference = type.copy ();
                decl.type_reference.is_ref = false;
@@ -983,7 +983,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                }
        }
 
-       private CCodeExpression get_unref_expression (CCodeExpression! cvar, TypeReference! type, Expression expr) {
+       public CCodeExpression get_unref_expression (CCodeExpression! cvar, TypeReference! type, Expression expr) {
                /* (foo == NULL ? NULL : foo = (unref (foo), NULL)) */
                
                /* can be simplified to
@@ -2097,7 +2097,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                visit_expression (expr);
        }
 
-       private CCodeExpression! get_array_length_cexpression (Expression! array_expr, int dim) {
+       public CCodeExpression! get_array_length_cexpression (Expression! array_expr, int dim) {
                bool is_out = false;
        
                if (array_expr is UnaryExpression) {
@@ -2773,7 +2773,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                return result;
        }
 
-       private CCodeExpression! convert_to_generic_pointer (CCodeExpression! cexpr, TypeReference! actual_type) {
+       public CCodeExpression! convert_to_generic_pointer (CCodeExpression! cexpr, TypeReference! actual_type) {
                var result = cexpr;
                if (actual_type.data_type is Struct) {
                        var st = (Struct) actual_type.data_type;
@@ -2790,7 +2790,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                return result;
        }
 
-       private CCodeExpression! get_implicit_cast_expression (CCodeExpression! cexpr, TypeReference expression_type, TypeReference! target_type) {
+       public CCodeExpression! get_implicit_cast_expression (CCodeExpression! cexpr, TypeReference expression_type, TypeReference! target_type) {
                if (null == expression_type) {
                        return cexpr;
                }
@@ -2819,6 +2819,61 @@ public class Vala.CCodeGenerator : CodeGenerator {
                        return cexpr;
                }
        }
+
+       public override void visit_assignment (Assignment! a) {
+               a.code_binding.emit ();
+       }
+
+       public CCodeFunctionCall get_property_set_call (Property! prop, MemberAccess! ma, CCodeExpression! cexpr) {
+               var cl = (Class) prop.parent_symbol;
+               var set_func = "g_object_set";
+               
+               var base_property = prop;
+               if (!prop.no_accessor_method) {
+                       if (prop.base_property != null) {
+                               base_property = prop.base_property;
+                       } else if (prop.base_interface_property != null) {
+                               base_property = prop.base_interface_property;
+                       }
+                       var base_property_type = (DataType) base_property.parent_symbol;
+                       set_func = "%s_set_%s".printf (base_property_type.get_lower_case_cname (null), base_property.name);
+               }
+               
+               var ccall = new CCodeFunctionCall (new CCodeIdentifier (set_func));
+
+               /* target instance is first argument */
+               CCodeExpression instance;
+
+               TypeReference instance_expression_type;
+               if (ma.inner == null) {
+                       instance = new CCodeIdentifier ("self");
+                       instance_expression_type = new TypeReference ();
+                       instance_expression_type.data_type = current_type_symbol;
+               } else {
+                       instance = (CCodeExpression) ma.inner.ccodenode;
+                       instance_expression_type = ma.inner.static_type;
+               }
+
+               var instance_target_type = new TypeReference ();
+               instance_target_type.data_type = (DataType) base_property.parent_symbol;
+               instance = get_implicit_cast_expression (instance, instance_expression_type, instance_target_type);
+
+               ccall.add_argument (instance);
+
+               if (prop.no_accessor_method) {
+                       /* property name is second argument of g_object_set */
+                       ccall.add_argument (prop.get_canonical_cconstant ());
+               }
+                       
+               ccall.add_argument (cexpr);
+               
+               if (prop.no_accessor_method) {
+                       ccall.add_argument (new CCodeConstant ("NULL"));
+               }
+
+               return ccall;
+       }
+
        public override CodeBinding create_namespace_binding (Namespace! node) {
                return null;
        }
@@ -3092,6 +3147,6 @@ public class Vala.CCodeGenerator : CodeGenerator {
        }
 
        public override CodeBinding create_assignment_binding (Assignment! node) {
-               return null;
+               return new CCodeAssignmentBinding (this, node);
        }
 }
index e1bf6af..f17de84 100644 (file)
@@ -453,7 +453,7 @@ public class Vala.CCodeGenerator {
                source_type_member_definition.append (function);
        }
        
-       private CCodeIdentifier! get_value_setter_function (TypeReference! type_reference) {
+       public CCodeIdentifier! get_value_setter_function (TypeReference! type_reference) {
                if (type_reference.data_type != null) {
                        return new CCodeIdentifier (type_reference.data_type.get_set_value_function ());
                } else {
index 7995562..54a326e 100644 (file)
@@ -34,7 +34,7 @@ public class Vala.CCodeGenerator {
                }
        }
        
-       private string get_signal_marshaller_function (Signal! sig, string prefix = null) {
+       public string get_signal_marshaller_function (Signal! sig, string prefix = null) {
                var signature = get_signal_signature (sig);
                string ret;
                var params = sig.get_parameters ();
index f38dd08..aa3f9d0 100644 (file)
@@ -26,4 +26,8 @@ using GLib;
  * The link between a source code node and generated code.
  */
 public abstract class Vala.CodeBinding : Object {
+       /**
+        * Generate code for this source code node.
+        */
+       public abstract void emit ();
 }
index 16d083d..306a9fe 100644 (file)
@@ -33,6 +33,8 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
         */
        public bool memory_management { get; set; }
 
+       private CodeContext context;
+
        Symbol root_symbol;
        Symbol current_symbol;
        SourceFile current_source_file;
@@ -78,6 +80,8 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
         * @param context a code context
         */
        public void analyze (CodeContext! context) {
+               this.context = context;
+
                root_symbol = context.root;
 
                bool_type = new TypeReference ();
@@ -497,7 +501,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        var left = new MemberAccess (new MemberAccess.simple ("this"), p.name);
                        var right = new MemberAccess.simple (p.name);
 
-                       method_body.add_statement (new ExpressionStatement (new Assignment (left, right), p.source_reference));
+                       method_body.add_statement (new ExpressionStatement (context.create_assignment (left, right), p.source_reference));
                }
        }
 
@@ -605,7 +609,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                                if (acc.readable) {
                                        acc.body.add_statement (new ReturnStatement (new MemberAccess.simple ("_%s".printf (acc.prop.name)), acc.source_reference));
                                } else {
-                                       acc.body.add_statement (new ExpressionStatement (new Assignment (new MemberAccess.simple ("_%s".printf (acc.prop.name)), new MemberAccess.simple ("value")), acc.source_reference));
+                                       acc.body.add_statement (new ExpressionStatement (context.create_assignment (new MemberAccess.simple ("_%s".printf (acc.prop.name)), new MemberAccess.simple ("value")), acc.source_reference));
                                }
                        }
 
@@ -2098,7 +2102,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        var old_value = new MemberAccess (ma.inner, ma.member_name, expr.inner.source_reference);
                        var bin = new BinaryExpression (expr.operator == UnaryOperator.INCREMENT ? BinaryOperator.PLUS : BinaryOperator.MINUS, old_value, new LiteralExpression (new IntegerLiteral ("1")), expr.source_reference);
 
-                       var assignment = new Assignment (ma, bin, AssignmentOperator.SIMPLE, expr.source_reference);
+                       var assignment = context.create_assignment (ma, bin, AssignmentOperator.SIMPLE, expr.source_reference);
                        var parenthexp = new ParenthesizedExpression (assignment, expr.source_reference);
                        expr.parent_node.replace (expr, parenthexp);
                        parenthexp.accept (this);