diff options
author | Juerg Billeter <j@bitron.ch> | 2007-09-27 11:59:26 +0000 |
---|---|---|
committer | Jürg Billeter <juergbi@src.gnome.org> | 2007-09-27 11:59:26 +0000 |
commit | b1e049d2636afdd6480a0c06e834c736fcd9998f (patch) | |
tree | affd2783be492de57ca72182b9f4b5ddbda20ba4 | |
parent | 2e425413261560afc9cc903efda6b805ccbed42f (diff) | |
download | vala-b1e049d2636afdd6480a0c06e834c736fcd9998f.tar.gz |
add CCodeExpressionBinding and CCodeAssignmentBinding classes and move
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
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | gobject/Makefile.am | 12 | ||||
-rw-r--r-- | gobject/valaccodeassignmentbinding.vala (renamed from gobject/valaccodegeneratorassignment.vala) | 237 | ||||
-rw-r--r-- | gobject/valaccodeexpressionbinding.vala | 30 | ||||
-rw-r--r-- | gobject/valaccodegenerator.vala | 131 | ||||
-rw-r--r-- | gobject/valaccodegeneratorclass.vala | 2 | ||||
-rw-r--r-- | gobject/valaccodegeneratorsignal.vala | 2 | ||||
-rw-r--r-- | vala/valacodebinding.vala | 4 | ||||
-rw-r--r-- | vala/valasemanticanalyzer.vala | 10 |
9 files changed, 252 insertions, 188 deletions
@@ -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 diff --git a/gobject/Makefile.am b/gobject/Makefile.am index fe6f7d4bc..b2bb1680e 100644 --- a/gobject/Makefile.am +++ b/gobject/Makefile.am @@ -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 \ diff --git a/gobject/valaccodegeneratorassignment.vala b/gobject/valaccodeassignmentbinding.vala index 4e2aac9b3..22494380e 100644 --- a/gobject/valaccodegeneratorassignment.vala +++ b/gobject/valaccodeassignmentbinding.vala @@ -1,4 +1,4 @@ -/* valaccodegeneratorassignment.vala +/* valaccodeassignmentbinding.vala * * Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini * @@ -18,26 +18,30 @@ * * 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 index 000000000..bb2c5c4ed --- /dev/null +++ b/gobject/valaccodeexpressionbinding.vala @@ -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; } +} diff --git a/gobject/valaccodegenerator.vala b/gobject/valaccodegenerator.vala index b3f8b35f3..18182d4bf 100644 --- a/gobject/valaccodegenerator.vala +++ b/gobject/valaccodegenerator.vala @@ -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); } } diff --git a/gobject/valaccodegeneratorclass.vala b/gobject/valaccodegeneratorclass.vala index e1bf6afc9..f17de84fa 100644 --- a/gobject/valaccodegeneratorclass.vala +++ b/gobject/valaccodegeneratorclass.vala @@ -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 { diff --git a/gobject/valaccodegeneratorsignal.vala b/gobject/valaccodegeneratorsignal.vala index 7995562c0..54a326e3b 100644 --- a/gobject/valaccodegeneratorsignal.vala +++ b/gobject/valaccodegeneratorsignal.vala @@ -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 (); diff --git a/vala/valacodebinding.vala b/vala/valacodebinding.vala index f38dd0828..aa3f9d033 100644 --- a/vala/valacodebinding.vala +++ b/vala/valacodebinding.vala @@ -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 (); } diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 16d083de5..306a9fe13 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -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); |