Commit 58e204da authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter

split code generator update

2007-05-03  Jürg Billeter  <j@bitron.ch>

	* gobject/valacodegenerator.vala,
	  gobject/valacodegeneratorassignment.vala,
	  gobject/valacodegeneratorclass.vala,
	  gobject/valacodegeneratorinterface.vala,
	  gobject/valacodegeneratorinvocationexpression.vala
	  gobject/valacodegeneratormemberaccess.vala,
	  gobject/valacodegeneratormethod.vala,
	  gobject/valacodegeneratorsignal.vala,
	  gobject/valacodegeneratorsourcefile.vala, 
	  gobject/valacodegeneratorstruct.vala: split code generator
	* gobject/Makefile.am, vapigen/Makefile.am: update

svn path=/trunk/; revision=306
parent ec85900a
2007-05-03 Jürg Billeter <j@bitron.ch>
* gobject/valacodegenerator.vala,
gobject/valacodegeneratorassignment.vala,
gobject/valacodegeneratorclass.vala,
gobject/valacodegeneratorinterface.vala,
gobject/valacodegeneratorinvocationexpression.vala
gobject/valacodegeneratormemberaccess.vala,
gobject/valacodegeneratormethod.vala,
gobject/valacodegeneratorsignal.vala,
gobject/valacodegeneratorsourcefile.vala,
gobject/valacodegeneratorstruct.vala: split code generator
* gobject/Makefile.am, vapigen/Makefile.am: update
2007-05-03 Jürg Billeter <j@bitron.ch>
* gobject/valacodegenerator.vala: move code generator to new gobject
......
......@@ -15,12 +15,48 @@ libvala_la_SOURCES = \
valacodegenerator.c \
valacodegenerator.h \
valacodegenerator.vala \
valacodegeneratorassignment.c \
valacodegeneratorassignment.h \
valacodegeneratorassignment.vala \
valacodegeneratorclass.c \
valacodegeneratorclass.h \
valacodegeneratorclass.vala \
valacodegeneratorinterface.c \
valacodegeneratorinterface.h \
valacodegeneratorinterface.vala \
valacodegeneratorinvocationexpression.c \
valacodegeneratorinvocationexpression.h \
valacodegeneratorinvocationexpression.vala \
valacodegeneratormemberaccess.c \
valacodegeneratormemberaccess.h \
valacodegeneratormemberaccess.vala \
valacodegeneratormethod.c \
valacodegeneratormethod.h \
valacodegeneratormethod.vala \
valacodegeneratorsignal.c \
valacodegeneratorsignal.h \
valacodegeneratorsignal.vala \
valacodegeneratorsourcefile.c \
valacodegeneratorsourcefile.h \
valacodegeneratorsourcefile.vala \
valacodegeneratorstruct.c \
valacodegeneratorstruct.h \
valacodegeneratorstruct.vala \
$(NULL)
gobjectincludedir = $(includedir)/vala-1.0/gobject
gobjectinclude_HEADERS = \
valacodegenerator.h \
valacodegeneratorassignment.h \
valacodegeneratorclass.h \
valacodegeneratorinterface.h \
valacodegeneratorinvocationexpression.h \
valacodegeneratormemberaccess.h \
valacodegeneratormethod.h \
valacodegeneratorsignal.h \
valacodegeneratorsourcefile.h \
valacodegeneratorstruct.h \
$(NULL)
gobject.vala gobject.vala.stamp: $(filter %.vala,$(libvala_la_SOURCES))
......
This diff is collapsed.
/* valacodegeneratorassignment.vala
*
* Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini
*
* 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 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>
* Raffaele Sandrini <rasa@gmx.ch>
*/
using GLib;
public class Vala.CodeGenerator {
public override void visit_end_assignment (Assignment! a) {
MemberAccess ma = null;
if (a.left is MemberAccess) {
ma = (MemberAccess)a.left;
}
if (a.left.symbol_reference != null && a.left.symbol_reference.node is Property) {
var prop = (Property) a.left.symbol_reference.node;
if (current_class != null && ma.inner == null && in_creation_method) {
// 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");
var cnameassign = new CCodeAssignment (cnamemember, prop.get_canonical_cconstant ());
ccomma.append_expression (cnameassign);
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 (prop.type_reference.data_type.get_type_id ()));
ccomma.append_expression (cvalueinit);
// set GValue for current parameter
var cvalueset = new CCodeFunctionCall (get_value_setter_function (prop.type_reference));
cvalueset.add_argument (gvaluearg);
cvalueset.add_argument ((CCodeExpression) a.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;
} else {
ref CCodeExpression cexpr = (CCodeExpression) a.right.ccodenode;
if (!prop.no_accessor_method
&& prop.type_reference.data_type != null
&& prop.type_reference.data_type.is_reference_type ()
&& a.right.static_type.data_type != null
&& prop.type_reference.data_type != a.right.static_type.data_type) {
/* cast is necessary */
var ccast = new CCodeFunctionCall (new CCodeIdentifier (prop.type_reference.data_type.get_upper_case_cname (null)));
ccast.add_argument (cexpr);
cexpr = ccast;
}
if (a.operator != AssignmentOperator.SIMPLE) {
CCodeBinaryOperator cop;
if (a.operator == AssignmentOperator.BITWISE_OR) {
cop = CCodeBinaryOperator.BITWISE_OR;
} else if (a.operator == AssignmentOperator.BITWISE_AND) {
cop = CCodeBinaryOperator.BITWISE_AND;
} else if (a.operator == AssignmentOperator.BITWISE_XOR) {
cop = CCodeBinaryOperator.BITWISE_XOR;
} else if (a.operator == AssignmentOperator.ADD) {
cop = CCodeBinaryOperator.PLUS;
} else if (a.operator == AssignmentOperator.SUB) {
cop = CCodeBinaryOperator.MINUS;
} else if (a.operator == AssignmentOperator.MUL) {
cop = CCodeBinaryOperator.MUL;
} else if (a.operator == AssignmentOperator.DIV) {
cop = CCodeBinaryOperator.DIV;
} else if (a.operator == AssignmentOperator.PERCENT) {
cop = CCodeBinaryOperator.MOD;
} else if (a.operator == AssignmentOperator.SHIFT_LEFT) {
cop = CCodeBinaryOperator.SHIFT_LEFT;
} else if (a.operator == AssignmentOperator.SHIFT_RIGHT) {
cop = CCodeBinaryOperator.SHIFT_RIGHT;
}
cexpr = new CCodeBinaryExpression (cop, (CCodeExpression) a.left.ccodenode, new CCodeParenthesizedExpression (cexpr));
}
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;
}
} else if (a.left.symbol_reference != null && a.left.symbol_reference.node is Signal) {
var sig = (Signal) a.left.symbol_reference.node;
var m = (Method) a.right.symbol_reference.node;
string connect_func;
bool disconnect = false;
if (a.operator == AssignmentOperator.ADD) {
connect_func = "g_signal_connect_object";
if (!m.instance) {
connect_func = "g_signal_connect";
}
} else if (a.operator == AssignmentOperator.SUB) {
connect_func = "g_signal_handlers_disconnect_matched";
disconnect = true;
} else {
a.error = true;
Report.error (a.source_reference, "Specified compound assignment type for signals not supported.");
return;
}
var ccall = new CCodeFunctionCall (new CCodeIdentifier (connect_func));
if (ma.inner != null) {
ccall.add_argument ((CCodeExpression) ma.inner.ccodenode);
} else {
ccall.add_argument (new CCodeIdentifier ("self"));
}
if (!disconnect) {
ccall.add_argument (sig.get_canonical_cconstant ());
} else {
ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA"));
// get signal id
var ccomma = new CCodeCommaExpression ();
var temp_decl = get_temp_variable_declarator (uint_type);
temp_vars.prepend (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.symbol.parent_symbol.node;
parse_call.add_argument (new CCodeIdentifier (decl_type.get_type_id ()));
parse_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_decl.name)));
parse_call.add_argument (new CCodeConstant ("NULL"));
parse_call.add_argument (new CCodeConstant ("FALSE"));
ccomma.append_expression (parse_call);
ccomma.append_expression (new CCodeIdentifier (temp_decl.name));
ccall.add_argument (ccomma);
ccall.add_argument (new CCodeConstant ("0"));
ccall.add_argument (new CCodeConstant ("NULL"));
}
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 (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) {
ccall.add_argument (new CCodeIdentifier ("self"));
}
if (!disconnect) {
ccall.add_argument (new CCodeConstant ("0"));
}
} else {
ccall.add_argument (new CCodeConstant ("NULL"));
}
a.ccodenode = ccall;
} else {
/* explicitly use strong reference as ccast gets
* unrefed at end of inner block
*/
ref CCodeExpression rhs = (CCodeExpression) a.right.ccodenode;
if (a.left.static_type.data_type != null
&& a.right.static_type.data_type != null
&& a.left.static_type.data_type.is_reference_type ()
&& a.right.static_type.data_type != a.left.static_type.data_type) {
var ccast = new CCodeFunctionCall (new CCodeIdentifier (a.left.static_type.data_type.get_upper_case_cname (null)));
ccast.add_argument (rhs);
rhs = ccast;
}
bool unref_old = (memory_management && a.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 (unref_old || array) {
var ccomma = new CCodeCommaExpression ();
var temp_decl = get_temp_variable_declarator (a.left.static_type);
temp_vars.prepend (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));
}
if (array) {
var lhs_array_len = get_array_length_cexpression (a.left, 1);
var rhs_array_len = get_array_length_cexpression (a.right, 1);
ccomma.append_expression (new CCodeAssignment (lhs_array_len, rhs_array_len));
}
ccomma.append_expression (new CCodeIdentifier (temp_decl.name));
rhs = ccomma;
}
var cop = CCodeAssignmentOperator.SIMPLE;
if (a.operator == AssignmentOperator.BITWISE_OR) {
cop = CCodeAssignmentOperator.BITWISE_OR;
} else if (a.operator == AssignmentOperator.BITWISE_AND) {
cop = CCodeAssignmentOperator.BITWISE_AND;
} else if (a.operator == AssignmentOperator.BITWISE_XOR) {
cop = CCodeAssignmentOperator.BITWISE_XOR;
} else if (a.operator == AssignmentOperator.ADD) {
cop = CCodeAssignmentOperator.ADD;
} else if (a.operator == AssignmentOperator.SUB) {
cop = CCodeAssignmentOperator.SUB;
} else if (a.operator == AssignmentOperator.MUL) {
cop = CCodeAssignmentOperator.MUL;
} else if (a.operator == AssignmentOperator.DIV) {
cop = CCodeAssignmentOperator.DIV;
} else if (a.operator == AssignmentOperator.PERCENT) {
cop = CCodeAssignmentOperator.PERCENT;
} else if (a.operator == AssignmentOperator.SHIFT_LEFT) {
cop = CCodeAssignmentOperator.SHIFT_LEFT;
} else if (a.operator == AssignmentOperator.SHIFT_RIGHT) {
cop = CCodeAssignmentOperator.SHIFT_RIGHT;
}
a.ccodenode = new CCodeAssignment ((CCodeExpression) a.left.ccodenode, rhs, cop);
}
}
private ref CCodeFunctionCall get_property_set_call (Property! prop, MemberAccess! ma, CCodeExpression! cexpr) {
var cl = (Class) prop.symbol.parent_symbol.node;
var set_func = "g_object_set";
if (!prop.no_accessor_method) {
set_func = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
}
var ccall = new CCodeFunctionCall (new CCodeIdentifier (set_func));
/* target instance is first argument */
ref CCodeExpression instance;
var req_cast = false;
if (ma.inner == null) {
instance = new CCodeIdentifier ("self");
/* require casts for inherited properties */
req_cast = (prop.symbol.parent_symbol != current_type_symbol);
} else {
instance = (CCodeExpression) ma.inner.ccodenode;
/* require casts if the type of the used instance is
* different than the type which declared the property */
req_cast = prop.symbol.parent_symbol.node != ma.inner.static_type.data_type;
}
if (req_cast && ((DataType) prop.symbol.parent_symbol.node).is_reference_type ()) {
var ccast = new CCodeFunctionCall (new CCodeIdentifier (((DataType) prop.symbol.parent_symbol.node).get_upper_case_cname (null)));
ccast.add_argument (instance);
instance = ccast;
}
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;
}
}
This diff is collapsed.
/* valacodegeneratorinterface.vala
*
* Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini
*
* 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 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>
* Raffaele Sandrini <rasa@gmx.ch>
*/
using GLib;
public class Vala.CodeGenerator {
public override void visit_begin_interface (Interface! iface) {
current_symbol = iface.symbol;
current_type_symbol = iface.symbol;
if (iface.is_static) {
return;
}
type_struct = new CCodeStruct ("_%s".printf (iface.get_type_cname ()));
header_type_declaration.append (new CCodeNewline ());
var macro = "(%s_get_type ())".printf (iface.get_lower_case_cname (null));
header_type_declaration.append (new CCodeMacroReplacement (iface.get_upper_case_cname ("TYPE_"), macro));
macro = "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (iface.get_upper_case_cname ("TYPE_"), iface.get_cname ());
header_type_declaration.append (new CCodeMacroReplacement ("%s(obj)".printf (iface.get_upper_case_cname (null)), macro));
macro = "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (iface.get_upper_case_cname ("TYPE_"));
header_type_declaration.append (new CCodeMacroReplacement ("%s(obj)".printf (iface.get_upper_case_cname ("IS_")), macro));
macro = "(G_TYPE_INSTANCE_GET_INTERFACE ((obj), %s, %s))".printf (iface.get_upper_case_cname ("TYPE_"), iface.get_type_cname ());
header_type_declaration.append (new CCodeMacroReplacement ("%s_GET_INTERFACE(obj)".printf (iface.get_upper_case_cname (null)), macro));
header_type_declaration.append (new CCodeNewline ());
if (iface.source_reference.file.cycle == null) {
header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (iface.get_cname ()), new CCodeVariableDeclarator (iface.get_cname ())));
header_type_declaration.append (new CCodeTypeDefinition ("struct %s".printf (type_struct.name), new CCodeVariableDeclarator (iface.get_type_cname ())));
}
type_struct.add_field ("GTypeInterface", "parent");
if (iface.source_reference.comment != null) {
header_type_definition.append (new CCodeComment (iface.source_reference.comment));
}
header_type_definition.append (type_struct);
}
public override void visit_end_interface (Interface! iface) {
if (!iface.is_static) {
add_interface_base_init_function (iface);
var type_fun = new InterfaceRegisterFunction (iface);
type_fun.init_from_type ();
header_type_member_declaration.append (type_fun.get_declaration ());
source_type_member_definition.append (type_fun.get_definition ());
}
current_type_symbol = null;
}
private ref CCodeFunctionCall! get_param_spec (Property! prop) {
var cspec = new CCodeFunctionCall ();
cspec.add_argument (prop.get_canonical_cconstant ());
cspec.add_argument (new CCodeConstant ("\"foo\""));
cspec.add_argument (new CCodeConstant ("\"bar\""));
if (prop.type_reference.data_type is Class || prop.type_reference.data_type is Interface) {
cspec.call = new CCodeIdentifier ("g_param_spec_object");
cspec.add_argument (new CCodeIdentifier (prop.type_reference.data_type.get_upper_case_cname ("TYPE_")));
} else if (prop.type_reference.data_type == string_type.data_type) {
cspec.call = new CCodeIdentifier ("g_param_spec_string");
cspec.add_argument (new CCodeConstant ("NULL"));
} else if (prop.type_reference.data_type == int_type.data_type
|| prop.type_reference.data_type is Enum) {
cspec.call = new CCodeIdentifier ("g_param_spec_int");
cspec.add_argument (new CCodeConstant ("G_MININT"));
cspec.add_argument (new CCodeConstant ("G_MAXINT"));
cspec.add_argument (new CCodeConstant ("0"));
} else if (prop.type_reference.data_type == uint_type.data_type) {
cspec.call = new CCodeIdentifier ("g_param_spec_uint");
cspec.add_argument (new CCodeConstant ("0"));
cspec.add_argument (new CCodeConstant ("G_MAXUINT"));
cspec.add_argument (new CCodeConstant ("0U"));
} else if (prop.type_reference.data_type == long_type.data_type) {
cspec.call = new CCodeIdentifier ("g_param_spec_long");
cspec.add_argument (new CCodeConstant ("G_MINLONG"));
cspec.add_argument (new CCodeConstant ("G_MAXLONG"));
cspec.add_argument (new CCodeConstant ("0L"));
} else if (prop.type_reference.data_type == ulong_type.data_type) {
cspec.call = new CCodeIdentifier ("g_param_spec_ulong");
cspec.add_argument (new CCodeConstant ("0"));
cspec.add_argument (new CCodeConstant ("G_MAXULONG"));
cspec.add_argument (new CCodeConstant ("0UL"));
} else if (prop.type_reference.data_type == bool_type.data_type) {
cspec.call = new CCodeIdentifier ("g_param_spec_boolean");
cspec.add_argument (new CCodeConstant ("FALSE"));
} else if (prop.type_reference.data_type == float_type.data_type) {
cspec.call = new CCodeIdentifier ("g_param_spec_float");
cspec.add_argument (new CCodeConstant ("-G_MAXFLOAT"));
cspec.add_argument (new CCodeConstant ("G_MAXFLOAT"));
cspec.add_argument (new CCodeConstant ("0.0F"));
} else if (prop.type_reference.data_type == double_type.data_type) {
cspec.call = new CCodeIdentifier ("g_param_spec_double");
cspec.add_argument (new CCodeConstant ("-G_MAXDOUBLE"));
cspec.add_argument (new CCodeConstant ("G_MAXDOUBLE"));
cspec.add_argument (new CCodeConstant ("0.0"));
} else {
cspec.call = new CCodeIdentifier ("g_param_spec_pointer");
}
var pflags = "G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB";
if (prop.get_accessor != null) {
pflags = "%s%s".printf (pflags, " | G_PARAM_READABLE");
}
if (prop.set_accessor != null) {
pflags = "%s%s".printf (pflags, " | G_PARAM_WRITABLE");
if (prop.set_accessor.construction) {
if (prop.set_accessor.writable) {
pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT");
} else {
pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT_ONLY");
}
}
}
cspec.add_argument (new CCodeConstant (pflags));
return cspec;
}
private ref CCodeFunctionCall! get_signal_creation (Signal! sig, DataType! type) {
var csignew = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_new"));
csignew.add_argument (new CCodeConstant ("\"%s\"".printf (sig.name)));
csignew.add_argument (new CCodeIdentifier (type.get_upper_case_cname ("TYPE_")));
csignew.add_argument (new CCodeConstant ("G_SIGNAL_RUN_LAST"));
csignew.add_argument (new CCodeConstant ("0"));
csignew.add_argument (new CCodeConstant ("NULL"));
csignew.add_argument (new CCodeConstant ("NULL"));
string marshaller = get_signal_marshaller_function (sig);
var marshal_arg = new CCodeIdentifier (marshaller);
csignew.add_argument (marshal_arg);
var params = sig.get_parameters ();
var params_len = params.length ();
if (sig.return_type.type_parameter != null) {
csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
} else if (sig.return_type.data_type == null) {
csignew.add_argument (new CCodeConstant ("G_TYPE_NONE"));
} else {
csignew.add_argument (new CCodeConstant (sig.return_type.data_type.get_type_id ()));
}
csignew.add_argument (new CCodeConstant ("%d".printf (params_len)));
foreach (FormalParameter param in params) {
if (param.type_reference.type_parameter != null) {
csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
} else {
csignew.add_argument (new CCodeConstant (param.type_reference.data_type.get_type_id ()));
}
}
marshal_arg.name = marshaller;
return csignew;
}
private void add_interface_base_init_function (Interface! iface) {
var base_init = new CCodeFunction ("%s_base_init".printf (iface.get_lower_case_cname (null)), "void");
base_init.add_parameter (new CCodeFormalParameter ("iface", "%sIface *".printf (iface.get_cname ())));
base_init.modifiers = CCodeModifiers.STATIC;
var init_block = new CCodeBlock ();
/* make sure not to run the initialization code twice */
base_init.block = new CCodeBlock ();
var decl = new CCodeDeclaration (bool_type.get_cname ());
decl.modifiers |= CCodeModifiers.STATIC;
decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("initialized", new CCodeConstant ("FALSE")));
base_init.block.add_statement (decl);
var cif = new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("initialized")), init_block);
base_init.block.add_statement (cif);
init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("initialized"), new CCodeConstant ("TRUE"))));
/* create properties */
var props = iface.get_properties ();
foreach (Property prop in props) {
var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_interface_install_property"));
cinst.add_argument (new CCodeIdentifier ("iface"));
cinst.add_argument (get_param_spec (prop));
init_block.add_statement (new CCodeExpressionStatement (cinst));
}
/* create signals */
foreach (Signal sig in iface.get_signals ()) {
init_block.add_statement (new CCodeExpressionStatement (get_signal_creation (sig, iface)));
}
source_type_member_definition.append (base_init);
}
}
/* valacodegeneratorinvocationexpression.vala
*
* Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini
*
* 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 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>
* Raffaele Sandrini <rasa@gmx.ch>
*/
using GLib;
public class Vala.CodeGenerator {
public override void visit_end_invocation_expression (InvocationExpression! expr) {
var ccall = new CCodeFunctionCall ((CCodeExpression) expr.call.ccodenode);
Method m = null;
List<weak FormalParameter> params;
if (!(expr.call is MemberAccess)) {
expr.error = true;
Report.error (expr.source_reference, "unsupported method invocation");
return;
}
var ma = (MemberAccess) expr.call;
if (expr.call.symbol_reference.node is Invokable) {
var i = (Invokable) expr.call.symbol_reference.node;
params = i.get_parameters ();
if (i is Method) {
m = (Method) i;
} else if (i is Signal) {
ccall = (CCodeFunctionCall) expr.call.ccodenode;
}
}
if (m is ArrayResizeMethod) {
var array = (Array) m.symbol.parent_symbol.node;
ccall.add_argument (new CCodeIdentifier (array.get_cname ()));
}
/* explicitly use strong reference as ccall gets unrefed
* at end of inner block
*/
ref CCodeExpression instance;
if (m != null && m.instance) {
var base_method = m;
if (m.base_interface_method != null) {
base_method = m.base_interface_method;
} else if (m.base_method != null) {
base_method = m.base_method;
}
var req_cast = false;
if (ma.inner == null) {
instance = new CCodeIdentifier ("self");
/* require casts for overriden and inherited methods */
req_cast = m.overrides || m.base_interface_method != null || (m.symbol.parent_symbol != current_type_symbol);
} else {
instance = (CCodeExpression) ma.inner.ccodenode;
/* reqiure casts if the type of the used instance is
* different than the type which declared the method */
req_cast = base_method.symbol.parent_symbol.node != ma.inner.static_type.data_type;
}
if (m.instance_by_reference && (ma.inner != null || m.symbol.parent_symbol != current_type_symbol)) {
instance = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance);
}
if (req_cast && ((DataType) m.symbol.parent_symbol.node).is_reference_type ()) {
// FIXME: use C cast if debugging disabled
var ccall = new CCodeFunctionCall (new CCodeIdentifier (((DataType) base_method.symbol.parent_symbol.node).get_upper_case_cname (null)));
ccall.add_argument (instance);
instance = ccall;
}
if (!m.instance_last) {
ccall.add_argument (instance);
}
}
bool ellipsis = false;