2008-04-23 Jürg Billeter <j@bitron.ch>
+ Add support for class constructors, class fields, and class
+ methods, fixes bug 507136
+
+2008-04-23 Jürg Billeter <j@bitron.ch>
+
* vala/valaparser.vala:
Fix nested namespaces
connect_func = codegen.dynamic_signal_binding ((DynamicSignal) sig).get_connect_wrapper_name ();
} else {
connect_func = "g_signal_connect_object";
- if (!m.instance) {
+ if (m.binding != MemberBinding.INSTANCE) {
connect_func = "g_signal_connect";
}
}
ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier (generate_signal_handler_wrapper (m, sig)), "GCallback"));
}
- if (m.instance) {
+ if (m.binding == MemberBinding.INSTANCE) {
// g_signal_connect_object or g_signal_handlers_disconnect_matched
// or dynamic_signal_connect or dynamic_signal_disconnect
var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
- if (m.instance) {
+ if (m.binding == MemberBinding.INSTANCE) {
carg_map.set (codegen.get_param_pos (m.cinstance_parameter_position), new CCodeIdentifier ("self"));
}
array = !(codegen.get_array_length_cexpression (assignment.left, 1) is CCodeConstant);
} else if (assignment.left.static_type is DelegateType) {
var delegate_type = (DelegateType) assignment.left.static_type;
- instance_delegate = delegate_type.delegate_symbol.instance;
+ instance_delegate = delegate_type.delegate_symbol.has_target;
}
if (unref_old || array || instance_delegate) {
int method_count = 0;
long blob_len = 0;
foreach (Method m in cl.get_methods ()) {
- if (m is CreationMethod || !m.instance) {
+ if (m is CreationMethod || m.binding != MemberBinding.INSTANCE) {
continue;
}
uint64_type = new ValueType ((Typesymbol) root_symbol.scope.lookup ("uint64"));
float_type = new ValueType ((Typesymbol) root_symbol.scope.lookup ("float"));
double_type = new ValueType ((Typesymbol) root_symbol.scope.lookup ("double"));
- string_type = new ClassType ((Class) root_symbol.scope.lookup ("string"));
+ string_type = new ClassInstanceType ((Class) root_symbol.scope.lookup ("string"));
substring_method = (Method) string_type.data_type.scope.lookup ("substring");
var glib_ns = root_symbol.scope.lookup ("GLib");
garray_type = (Typesymbol) glib_ns.scope.lookup ("Array");
gquark_type = new ValueType ((Typesymbol) glib_ns.scope.lookup ("Quark"));
- mutex_type = new ClassType ((Class) glib_ns.scope.lookup ("Mutex"));
+ mutex_type = new ClassInstanceType ((Class) glib_ns.scope.lookup ("Mutex"));
type_module_type = (Typesymbol) glib_ns.scope.lookup ("TypeModule");
foreach (FormalParameter param in d.get_parameters ()) {
cfundecl.add_parameter ((CCodeFormalParameter) param.ccodenode);
}
- if (d.instance) {
+ if (d.has_target) {
var cparam = new CCodeFormalParameter ("user_data", "void*");
cfundecl.add_parameter (cparam);
}
}
if (f.access != SymbolAccessibility.PRIVATE) {
- st = instance_struct;
- if (f.instance) {
+ if (f.binding == MemberBinding.INSTANCE) {
+ st = instance_struct;
+
lhs = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), f.get_cname ());
+ } else if (f.binding == MemberBinding.CLASS) {
+ st = type_struct;
} else {
var cdecl = new CCodeDeclaration (field_ctype);
cdecl.add_declarator (new CCodeVariableDeclarator (f.get_cname ()));
lhs = new CCodeIdentifier (f.get_cname ());
}
} else if (f.access == SymbolAccessibility.PRIVATE) {
- if (f.instance) {
+ if (f.binding == MemberBinding.INSTANCE) {
if (is_gtypeinstance) {
st = instance_priv_struct;
lhs = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), f.get_cname ());
}
}
- if (f.instance) {
+ if (f.binding == MemberBinding.INSTANCE) {
st.add_field (field_ctype, f.get_cname ());
if (f.type_reference is ArrayType && !f.no_array_length) {
// create fields to store array dimensions
}
} else if (f.type_reference is DelegateType) {
var delegate_type = (DelegateType) f.type_reference;
- if (delegate_type.delegate_symbol.instance) {
+ if (delegate_type.delegate_symbol.has_target) {
// create field to store delegate target
st.add_field ("gpointer", get_delegate_target_cname (f.name));
}
ma.symbol_reference = f;
instance_dispose_fragment.append (new CCodeExpressionStatement (get_unref_expression (lhs, f.type_reference, ma)));
}
+ } else if (f.binding == MemberBinding.CLASS) {
+ st.add_field (field_ctype, f.get_cname ());
} else {
/* add array length fields where necessary */
if (f.type_reference is ArrayType && !f.no_array_length) {
}
} else if (f.type_reference is DelegateType) {
var delegate_type = (DelegateType) f.type_reference;
- if (delegate_type.delegate_symbol.instance) {
+ if (delegate_type.delegate_symbol.has_target) {
// create field to store delegate target
var cdecl = new CCodeDeclaration ("gpointer");
cdecl.add_declarator (new CCodeVariableDeclarator (get_delegate_target_cname (f.get_cname ())));
ReferenceType this_type;
if (t is Class) {
- this_type = new ClassType ((Class) t);
+ this_type = new ClassInstanceType ((Class) t);
} else {
- this_type = new InterfaceType ((Interface) t);
+ this_type = new InterfaceInstanceType ((Interface) t);
}
var cselfparam = new CCodeFormalParameter ("self", this_type.get_cname ());
var cvalueparam = new CCodeFormalParameter ("value", prop.type_reference.get_cname (false, true));
var cl = (Class) c.parent_symbol;
- if (c.instance) {
+ if (c.binding == MemberBinding.INSTANCE) {
function = new CCodeFunction ("%s_constructor".printf (cl.get_lower_case_cname (null)), "GObject *");
function.modifiers = CCodeModifiers.STATIC;
source_type_member_definition.append (new CCodeComment (c.source_reference.comment));
}
source_type_member_definition.append (function);
- } else {
+ } else if (c.binding == MemberBinding.CLASS) {
+ // class constructor
+
+ var base_init = new CCodeFunction ("%s_base_init".printf (cl.get_lower_case_cname (null)), "void");
+ base_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
+ base_init.modifiers = CCodeModifiers.STATIC;
+
+ source_type_member_declaration.append (base_init.copy ());
+
+ base_init.block = (CCodeBlock) c.body.ccodenode;
+
+ source_type_member_definition.append (base_init);
+ } else if (c.binding == MemberBinding.STATIC) {
// static class constructor
// add to class_init
}
class_init_fragment.append (c.body.ccodenode);
+ } else {
+ Report.error (c.source_reference, "internal error: constructors must have instance, class, or static binding");
}
}
} else if (local.variable_type is DelegateType) {
var deleg_type = (DelegateType) local.variable_type;
var d = deleg_type.delegate_symbol;
- if (d.instance) {
+ if (d.has_target) {
// create variable to store delegate target
var target_var = new LocalVariable (new PointerType (new VoidType ()), get_delegate_target_cname (local.name));
temp_vars.insert (0, target_var);
} else if (local.variable_type is DelegateType) {
var deleg_type = (DelegateType) local.variable_type;
var d = deleg_type.delegate_symbol;
- if (d.instance) {
+ if (d.has_target) {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (local.variable_type, true, local);
cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier (it_name), new CCodeConstant ("1"))));
cblock.add_statement (cfor);
}
- } else if (stmt.collection.static_type.compatible (new ClassType (glist_type)) || stmt.collection.static_type.compatible (new ClassType (gslist_type))) {
+ } else if (stmt.collection.static_type.compatible (new ClassInstanceType (glist_type)) || stmt.collection.static_type.compatible (new ClassInstanceType (gslist_type))) {
var it_name = "%s_it".printf (stmt.variable_name);
var citdecl = new CCodeDeclaration (collection_type.get_cname ());
cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeMemberAccess.pointer (new CCodeIdentifier (it_name), "next")));
cblock.add_statement (cfor);
- } else if (iterable_type != null && stmt.collection.static_type.compatible (new InterfaceType (iterable_type))) {
+ } else if (iterable_type != null && stmt.collection.static_type.compatible (new InterfaceInstanceType (iterable_type))) {
var it_name = "%s_it".printf (stmt.variable_name);
var citdecl = new CCodeDeclaration (iterator_type.get_cname () + "*");
}
}
- if (field.instance) {
+ if (field.binding == MemberBinding.INSTANCE) {
var length_cname = get_array_length_cname (field.name, dim);
var instance_expression_type = get_data_type_for_symbol (base_type);
var instance_target_type = get_data_type_for_symbol ((Typesymbol) field.parent_symbol);
var invocation_expr = (InvocationExpression) delegate_expr;
return invocation_expr.delegate_target;
} else if (delegate_expr is LambdaExpression) {
- if ((current_method != null && current_method.instance) || in_constructor) {
+ if ((current_method != null && current_method.binding == MemberBinding.INSTANCE) || in_constructor) {
return new CCodeIdentifier ("self");
} else {
return new CCodeConstant ("NULL");
}
}
- if (field.instance) {
+ if (field.binding == MemberBinding.INSTANCE) {
var instance_expression_type = get_data_type_for_symbol (base_type);
var instance_target_type = get_data_type_for_symbol ((Typesymbol) field.parent_symbol);
CCodeExpression typed_inst = get_implicit_cast_expression (pub_inst, instance_expression_type, instance_target_type);
} else if (delegate_expr.symbol_reference is Method) {
var ma = (MemberAccess) delegate_expr;
if (ma.inner == null) {
- if ((current_method != null && current_method.instance) || in_constructor) {
+ if ((current_method != null && current_method.binding == MemberBinding.INSTANCE) || in_constructor) {
return new CCodeIdentifier ("self");
} else {
return new CCodeConstant ("NULL");
if (param != null && param.type_reference is DelegateType) {
var deleg_type = (DelegateType) param.type_reference;
var d = deleg_type.delegate_symbol;
- if (d.instance) {
+ if (d.has_target) {
creation_call.add_argument (get_delegate_target_cexpression (arg));
}
}
var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
- if (d.instance) {
+ if (d.has_target) {
var cparam = new CCodeFormalParameter ("self", "gpointer");
cparam_map.set (get_param_pos (d.cinstance_parameter_position), cparam);
}
var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
int i = 0;
- if (m.instance) {
+ if (m.binding == MemberBinding.INSTANCE) {
CCodeExpression arg;
- if (d.instance) {
+ if (d.has_target) {
arg = new CCodeIdentifier ("self");
} else {
// use first delegate parameter as instance
DataType type = null;
if (sym is Class) {
- type = new ClassType ((Class) sym);
+ type = new ClassInstanceType ((Class) sym);
} else if (sym is Interface) {
- type = new InterfaceType ((Interface) sym);
+ type = new InterfaceInstanceType ((Interface) sym);
} else if (sym is Struct) {
type = new ValueType ((Struct) sym);
} else if (sym is Enum) {
}
CCodeExpression instance;
- if (m != null && m.instance) {
+ if (m != null && m.binding == MemberBinding.INSTANCE) {
var base_method = m;
if (m.base_method != null) {
base_method = m.base_method;
}
carg_map.set (codegen.get_param_pos (m.cinstance_parameter_position), instance);
+ } else if (m != null && m.binding == MemberBinding.CLASS) {
+ var cl = (Class) m.parent_symbol;
+ var cast = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null) + "_CLASS"));
+ cast.add_argument (new CCodeIdentifier ("klass"));
+
+ carg_map.set (codegen.get_param_pos (m.cinstance_parameter_position), cast);
}
if (m is ArrayMoveMethod) {
} else if (param.type_reference is DelegateType) {
var deleg_type = (DelegateType) param.type_reference;
var d = deleg_type.delegate_symbol;
- if (d.instance) {
+ if (d.has_target) {
carg_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position), codegen.get_delegate_target_cexpression (arg));
multiple_cargs = true;
}
} else if (m != null && m.return_type is DelegateType) {
var deleg_type = (DelegateType) m.return_type;
var d = deleg_type.delegate_symbol;
- if (d.instance) {
+ if (d.has_target) {
var temp_var = codegen.get_temp_variable (new PointerType (new VoidType ()));
var temp_ref = new CCodeIdentifier (temp_var.name);
} else if (itype is DelegateType) {
var deleg_type = (DelegateType) itype;
var d = deleg_type.delegate_symbol;
- if (d.instance) {
+ if (d.has_target) {
carg_map.set (codegen.get_param_pos (d.cinstance_parameter_position), codegen.get_delegate_target_cexpression (expr.call));
}
}
last_pos = min_pos;
}
- if (m != null && m.instance && m.returns_modified_pointer) {
+ if (m != null && m.binding == MemberBinding.INSTANCE && m.returns_modified_pointer) {
expr.ccodenode = new CCodeAssignment (instance, ccall_expr);
} else {
/* cast pointer to actual type if this is a generic method return value */
expr.ccodenode = codegen.get_array_length_cexpression (expr.inner, 1);
} else if (expr.symbol_reference is Field) {
var f = (Field) expr.symbol_reference;
- if (f.instance) {
+ if (f.binding == MemberBinding.INSTANCE) {
var instance_expression_type = base_type;
var instance_target_type = codegen.get_data_type_for_symbol ((Typesymbol) f.parent_symbol);
CCodeExpression typed_inst = codegen.get_implicit_cast_expression (pub_inst, instance_expression_type, instance_target_type);
} else {
expr.ccodenode = new CCodeMemberAccess (inst, f.get_cname ());
}
+ } else if (f.binding == MemberBinding.CLASS) {
+ var cl = (Class) f.parent_symbol;
+ var cast = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null) + "_CLASS"));
+ cast.add_argument (new CCodeIdentifier ("klass"));
+ expr.ccodenode = new CCodeMemberAccess.pointer (cast, f.get_cname ());
} else {
expr.ccodenode = new CCodeIdentifier (f.get_cname ());
}
if (codegen.current_type_symbol != null) {
/* base type is available if this is a type method */
if (codegen.current_type_symbol is Class) {
- base_type = new ClassType ((Class) codegen.current_type_symbol);
+ base_type = new ClassInstanceType ((Class) codegen.current_type_symbol);
} else if (codegen.current_type_symbol is Interface) {
- base_type = new InterfaceType ((Interface) codegen.current_type_symbol);
+ base_type = new InterfaceInstanceType ((Interface) codegen.current_type_symbol);
} else {
base_type = new ValueType (codegen.current_type_symbol);
pub_inst = new CCodeIdentifier ("(*self)");
}
if (cl != null) {
- creturn_type = new ClassType (cl);
+ creturn_type = new ClassInstanceType (cl);
}
}
CCodeFunctionDeclarator vdeclarator = null;
- if (m.instance || (m.parent_symbol is Struct && m is CreationMethod)) {
+ if (m.binding == MemberBinding.INSTANCE || (m.parent_symbol is Struct && m is CreationMethod)) {
Typesymbol parent_type = find_parent_type (m);
DataType this_type;
if (parent_type is Class) {
- this_type = new ClassType ((Class) parent_type);
+ this_type = new ClassInstanceType ((Class) parent_type);
} else if (parent_type is Interface) {
- this_type = new InterfaceType ((Interface) parent_type);
+ this_type = new InterfaceInstanceType ((Interface) parent_type);
} else {
this_type = new ValueType (parent_type);
}
CCodeFormalParameter instance_param = null;
if (m.base_interface_method != null && !m.is_abstract && !m.is_virtual) {
- var base_type = new InterfaceType ((Interface) m.base_interface_method.parent_symbol);
+ var base_type = new InterfaceInstanceType ((Interface) m.base_interface_method.parent_symbol);
instance_param = new CCodeFormalParameter ("base", base_type.get_cname ());
} else if (m.overrides) {
- var base_type = new ClassType ((Class) m.base_method.parent_symbol);
+ var base_type = new ClassInstanceType ((Class) m.base_method.parent_symbol);
instance_param = new CCodeFormalParameter ("base", base_type.get_cname ());
} else {
if (m.parent_symbol is Struct && !((Struct) m.parent_symbol).is_simple_type ()) {
vdecl.add_declarator (vdeclarator);
codegen.type_struct.add_declaration (vdecl);
}
+ } else if (m.binding == MemberBinding.CLASS) {
+ Typesymbol parent_type = find_parent_type (m);
+ DataType this_type;
+ this_type = new ClassType ((Class) parent_type);
+ var class_param = new CCodeFormalParameter ("klass", this_type.get_cname ());
+ cparam_map.set (codegen.get_param_pos (m.cinstance_parameter_position), class_param);
}
if (in_fundamental_creation_method) {
ReferenceType base_expression_type;
if (m.overrides) {
base_method = m.base_method;
- base_expression_type = new ClassType ((Class) base_method.parent_symbol);
+ base_expression_type = new ClassInstanceType ((Class) base_method.parent_symbol);
} else {
base_method = m.base_interface_method;
- base_expression_type = new InterfaceType ((Interface) base_method.parent_symbol);
+ base_expression_type = new InterfaceInstanceType ((Interface) base_method.parent_symbol);
}
- var self_target_type = new ClassType (cl);
+ var self_target_type = new ClassInstanceType (cl);
CCodeExpression cself = codegen.get_implicit_cast_expression (new CCodeIdentifier ("base"), base_expression_type, self_target_type);
var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", cself));
cinit.append (cdecl);
- } else if (m.instance) {
+ } else if (m.binding == MemberBinding.INSTANCE) {
var ccheckstmt = create_method_type_check_statement (m, creturn_type, cl, true, "self");
ccheckstmt.line = codegen.function.line;
cinit.append (ccheckstmt);
ReferenceType this_type;
if (m.parent_symbol is Class) {
- this_type = new ClassType ((Class) m.parent_symbol);
+ this_type = new ClassInstanceType ((Class) m.parent_symbol);
} else {
- this_type = new InterfaceType ((Interface) m.parent_symbol);
+ this_type = new InterfaceInstanceType ((Interface) m.parent_symbol);
}
cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
if (param.type_reference is DelegateType) {
var deleg_type = (DelegateType) param.type_reference;
var d = deleg_type.delegate_symbol;
- if (d.instance) {
+ if (d.has_target) {
var cparam = new CCodeFormalParameter (codegen.get_delegate_target_cname (param.name), "void*");
cparam_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position), cparam);
carg_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position), new CCodeIdentifier (cparam.name));
// return delegate target if appropriate
var deleg_type = (DelegateType) creturn_type;
var d = deleg_type.delegate_symbol;
- if (d.instance) {
+ if (d.has_target) {
var cparam = new CCodeFormalParameter (codegen.get_delegate_target_cname ("result"), "void*");
cparam_map.set (codegen.get_param_pos (m.cdelegate_target_parameter_position), cparam);
carg_map.set (codegen.get_param_pos (m.cdelegate_target_parameter_position), new CCodeIdentifier (cparam.name));
if (param.type_reference is DelegateType) {
var deleg_type = (DelegateType) param.type_reference;
var d = deleg_type.delegate_symbol;
- if (d.instance) {
+ if (d.has_target) {
var cparam = new CCodeFormalParameter (codegen.get_delegate_target_cname (param.name), "void*");
cparam_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position), cparam);
}
// return delegate target if appropriate
var deleg_type = (DelegateType) creturn_type;
var d = deleg_type.delegate_symbol;
- if (d.instance) {
+ if (d.has_target) {
var cparam = new CCodeFormalParameter (codegen.get_delegate_target_cname ("result"), "void*");
cparam_map.set (codegen.get_param_pos (m.cdelegate_target_parameter_position), cparam);
}
return false;
}
- if (m.instance) {
+ if (m.binding == MemberBinding.INSTANCE) {
// method must be static
return false;
}
/* valaclassregisterfunction.vala
*
- * Copyright (C) 2006-2007 Jürg Billeter
+ * Copyright (C) 2006-2008 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
}
public override string get_base_init_func_name () {
- return "NULL";
+ if (class_reference.class_constructor != null) {
+ return "%s_base_init".printf (class_reference.get_lower_case_cname (null));
+ } else {
+ return "NULL";
+ }
}
public override string get_class_init_func_name () {
// write implemented interfaces
bool first = true;
foreach (DataType base_type in cl.get_base_types ()) {
- var iface_type = base_type as InterfaceType;
+ var iface_type = base_type as InterfaceInstanceType;
if (iface_type != null) {
if (first) {
write_indent ();
indent++;
foreach (DataType base_type in iface.get_prerequisites ()) {
- var class_type = base_type as ClassType;
- var iface_type = base_type as InterfaceType;
+ var class_type = base_type as ClassInstanceType;
+ var iface_type = base_type as InterfaceInstanceType;
if (class_type != null) {
write_indent ();
stream.printf ("<object name=\"%s\"/>\n", class_type.class_symbol.get_full_name ());
indent++;
DataType instance_type = null;
- if (m.instance) {
+ if (m.binding == MemberBinding.INSTANCE) {
instance_type = CCodeGenerator.get_data_type_for_symbol ((Typesymbol) m.parent_symbol);
}
valacfgbuilder.vala \
valacharacterliteral.vala \
valaclass.vala \
+ valaclassinstancetype.vala \
valaclasstype.vala \
valacodebinding.vala \
valacodecontext.vala \
valaintegerliteral.vala \
valaintegertype.vala \
valainterface.vala \
+ valainterfaceinstancetype.vala \
valainterfacetype.vala \
valainterfacewriter.vala \
valainvalidtype.vala \
public Constructor constructor { get; set; }
/**
+ * Specifies the class constructor.
+ */
+ public Constructor class_constructor { get; set; }
+
+ /**
* Specifies the static class constructor.
*/
public Constructor static_constructor { get; set; }
if (_destructor.this_parameter != null) {
_destructor.scope.remove (_destructor.this_parameter.name);
}
- _destructor.this_parameter = new FormalParameter ("this", new ClassType (this));
+ _destructor.this_parameter = new FormalParameter ("this", new ClassInstanceType (this));
_destructor.scope.add (_destructor.this_parameter.name, _destructor.this_parameter);
}
}
*/
public void add_field (Field f) {
fields.add (f);
- if (f.access == SymbolAccessibility.PRIVATE && f.instance) {
+ if (f.access == SymbolAccessibility.PRIVATE && f.binding == MemberBinding.INSTANCE) {
has_private_fields = true;
}
scope.add (f.name, f);
* @param m a method
*/
public void add_method (Method m) {
- if (m.instance || m is CreationMethod) {
+ if (m.binding == MemberBinding.INSTANCE || m is CreationMethod) {
if (m.this_parameter != null) {
m.scope.remove (m.this_parameter.name);
}
- m.this_parameter = new FormalParameter ("this", new ClassType (this));
+ m.this_parameter = new FormalParameter ("this", new ClassInstanceType (this));
m.scope.add (m.this_parameter.name, m.this_parameter);
}
if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
properties.add (prop);
scope.add (prop.name, prop);
- prop.this_parameter = new FormalParameter ("this", new ClassType (this));
+ prop.this_parameter = new FormalParameter ("this", new ClassInstanceType (this));
prop.scope.add (prop.this_parameter.name, prop.this_parameter);
if (!no_field && !external_package) {
constructor.accept (visitor);
}
+ if (class_constructor != null) {
+ class_constructor.accept (visitor);
+ }
+
if (static_constructor != null) {
static_constructor.accept (visitor);
}
--- /dev/null
+/* valaclassinstancetype.vala
+ *
+ * Copyright (C) 2007-2008 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;
+
+/**
+ * A class type.
+ */
+public class Vala.ClassInstanceType : ReferenceType {
+ /**
+ * The referred class.
+ */
+ public weak Class class_symbol { get; set; }
+
+ public ClassInstanceType (Class class_symbol) {
+ this.class_symbol = class_symbol;
+ data_type = class_symbol;
+ }
+
+ public override DataType copy () {
+ var result = new ClassInstanceType (class_symbol);
+ result.source_reference = source_reference;
+ result.transfers_ownership = transfers_ownership;
+ result.takes_ownership = takes_ownership;
+ result.nullable = nullable;
+ result.is_dynamic = is_dynamic;
+ result.floating_reference = floating_reference;
+
+ foreach (DataType arg in get_type_arguments ()) {
+ result.add_type_argument (arg.copy ());
+ }
+
+ return result;
+ }
+}
public ClassType (Class class_symbol) {
this.class_symbol = class_symbol;
- data_type = class_symbol;
}
public override DataType copy () {
return result;
}
+
+ public override string? get_cname (bool var_type, bool const_type) {
+ return "%sClass*".printf (class_symbol.get_cname ());
+ }
}
/**
* Specifies whether this is an instance or a class constructor.
*/
- public bool instance { get; set; default = true; }
+ public MemberBinding binding { get; set; default = MemberBinding.INSTANCE; }
/**
* Creates a new constructor.
* The reference to the object instance will be appended to the end of
* the argument list in the generated C code.
*/
- public bool instance { get; set; }
+ public bool has_target { get; set; }
/**
* Specifies the position of the instance parameter in the C function.
* an instance method is being compared to a static
* callback
*/
- if (first && m.instance && !instance) {
+ if (first && m.binding == MemberBinding.INSTANCE && !has_target) {
first = false;
continue;
}
/**
* Specifies whether this is an instance or a class destructor.
*/
- public bool instance { get; set; default = true; }
+ public MemberBinding binding { get; set; default = MemberBinding.INSTANCE; }
/**
* Creates a new destructor.
m.error = true;
return;
}
- if (m.instance) {
+ if (m.binding == MemberBinding.INSTANCE) {
m.this_parameter = new FormalParameter ("this", new ValueType (this));
m.scope.add (m.this_parameter.name, m.this_parameter);
}
m.error = true;
return;
}
- if (m.instance) {
+ if (m.binding == MemberBinding.INSTANCE) {
m.this_parameter = new FormalParameter ("this", new ValueType (this));
m.scope.add (m.this_parameter.name, m.this_parameter);
}
* Specifies whether this field may only be accessed with an instance of
* the contained type.
*/
- public bool instance {
- get { return _instance; }
- set { _instance = value; }
- }
+ public MemberBinding binding { get; set; default = MemberBinding.INSTANCE; }
/**
* Specifies whether the field is volatile. Volatile fields are
public bool no_array_length { get; set; }
private string cname;
- private bool _instance = true;
private bool lock_used = false;
* @return the name to be used in C code by default
*/
public string get_default_cname () {
- if (!instance) {
+ if (binding == MemberBinding.STATIC) {
return parent_symbol.get_lower_case_cprefix () + name;
} else {
return name;
m.error = true;
return;
}
- if (m.instance) {
- m.this_parameter = new FormalParameter ("this", new InterfaceType (this));
+ if (m.binding == MemberBinding.INSTANCE) {
+ m.this_parameter = new FormalParameter ("this", new InterfaceInstanceType (this));
m.scope.add (m.this_parameter.name, m.this_parameter);
}
if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
--- /dev/null
+/* valainterfaceinstancetype.vala
+ *
+ * Copyright (C) 2007-2008 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;
+
+/**
+ * An interface type.
+ */
+public class Vala.InterfaceInstanceType : ReferenceType {
+ /**
+ * The referred interface.
+ */
+ public weak Interface interface_symbol { get; set; }
+
+ public InterfaceInstanceType (Interface interface_symbol) {
+ this.interface_symbol = interface_symbol;
+ data_type = interface_symbol;
+ }
+
+ public override DataType copy () {
+ var result = new InterfaceInstanceType (interface_symbol);
+ result.source_reference = source_reference;
+ result.transfers_ownership = transfers_ownership;
+ result.takes_ownership = takes_ownership;
+ result.nullable = nullable;
+ result.is_dynamic = is_dynamic;
+ result.floating_reference = floating_reference;
+
+ foreach (DataType arg in get_type_arguments ()) {
+ result.add_type_argument (arg.copy ());
+ }
+
+ return result;
+ }
+}
public InterfaceType (Interface interface_symbol) {
this.interface_symbol = interface_symbol;
- data_type = interface_symbol;
}
public override DataType copy () {
return result;
}
+
+ public override string? get_cname (bool var_type, bool const_type) {
+ return "%sIface*".printf (interface_symbol.get_cname ());
+ }
}
write_indent ();
write_accessibility (cb);
- if (!cb.instance) {
+ if (!cb.has_target) {
write_string ("static ");
}
write_string ("delegate ");
write_identifier (datatype.name);
write_identifier (m.name.offset (".new".len ()));
write_string (" ");
- } else if (!m.instance) {
+ } else if (m.binding == MemberBinding.STATIC) {
write_string ("static ");
} else if (m.is_abstract) {
write_string ("abstract ");
cheader_filenames.add (filename);
}
}
+
+public enum MemberBinding {
+ INSTANCE,
+ CLASS,
+ STATIC
+}
+
* Specifies whether this method may only be called with an instance of
* the contained type.
*/
- public bool instance {
- get {
- return _instance;
- }
- set {
- _instance = value;
- }
- }
+ public MemberBinding binding { get; set; default = MemberBinding.INSTANCE; }
/**
* The name of the vfunc of this method as it is used in C code.
*/
public bool printf_format { get; set; }
- private bool _instance = true;
private Gee.List<FormalParameter> parameters = new ArrayList<FormalParameter> ();
private string cname;
private string _vfunc_name;
m.error = true;
return;
}
- if (m.instance) {
+ if (m.binding == MemberBinding.INSTANCE) {
Report.error (m.source_reference, "instance methods not allowed outside of data types");
m.error = true;
var mtype = expr.call.static_type as MethodType;
var ma = expr.call as MemberAccess;
- if (mtype != null && mtype.method_symbol.instance && ma != null) {
+ if (mtype != null && mtype.method_symbol.binding == MemberBinding.INSTANCE && ma != null) {
if (ma.inner == null) {
// implicit this call, always non-null
} else {
ns.add_delegate ((Delegate) sym);
} else if (sym is Method) {
var method = (Method) sym;
- method.instance = false;
+ method.binding = MemberBinding.STATIC;
ns.add_method (method);
} else if (sym is Field) {
var field = (Field) sym;
- field.instance = false;
+ field.binding = MemberBinding.STATIC;
ns.add_field (field);
} else if (sym is Constant) {
ns.add_constant ((Constant) sym);
&& !cl.is_static
&& cl.default_construction_method == null) {
var m = new CreationMethod (cl.name, null, cl.source_reference);
- m.instance = false;
+ m.binding = MemberBinding.STATIC;
m.access = SymbolAccessibility.PUBLIC;
m.body = new Block (cl.source_reference);
cl.add_method (m);
cl.add_property ((Property) sym);
} else if (sym is Constructor) {
var c = (Constructor) sym;
- if (c.instance) {
+ if (c.binding == MemberBinding.INSTANCE) {
cl.constructor = c;
+ } else if (c.binding == MemberBinding.CLASS) {
+ cl.class_constructor = c;
} else {
cl.static_constructor = c;
}
f.access = access;
set_attributes (f, attrs);
if (ModifierFlags.STATIC in flags) {
- f.instance = false;
+ f.binding = MemberBinding.STATIC;
+ } else if (ModifierFlags.CLASS in flags) {
+ f.binding = MemberBinding.CLASS;
}
if (accept (TokenType.ASSIGN)) {
f.initializer = parse_expression ();
method.access = access;
set_attributes (method, attrs);
if (ModifierFlags.STATIC in flags) {
- method.instance = false;
+ method.binding = MemberBinding.STATIC;
+ } else if (ModifierFlags.CLASS in flags) {
+ method.binding = MemberBinding.CLASS;
}
if (ModifierFlags.ABSTRACT in flags) {
method.is_abstract = true;
expect (TokenType.CONSTRUCT);
var c = new Constructor (get_src_com (begin));
if (ModifierFlags.STATIC in flags) {
- c.instance = false;
+ c.binding = MemberBinding.STATIC;
+ } else if (ModifierFlags.CLASS in flags) {
+ c.binding = MemberBinding.CLASS;
}
c.body = parse_block ();
return c;
}
method.access = access;
set_attributes (method, attrs);
- method.instance = false;
+ method.binding = MemberBinding.STATIC;
if (!accept (TokenType.SEMICOLON)) {
method.body = parse_block ();
}
d.access = access;
set_attributes (d, attrs);
if (!(ModifierFlags.STATIC in flags)) {
- d.instance = true;
+ d.has_target = true;
}
foreach (TypeParameter type_param in type_param_list) {
d.add_type_parameter (type_param);
* Specifies whether this field may only be accessed with an instance of
* the contained type.
*/
- public bool instance {
- get { return _instance; }
- set { _instance = value; }
- }
+ public MemberBinding binding { get; set; default = MemberBinding.INSTANCE; }
/**
* Specifies the virtual or abstract property this property overrides.
private bool lock_used = false;
private DataType _data_type;
- private bool _instance = true;
private string? _nick;
private string? _blurb;
root_symbol = context.root;
bool_type = new ValueType ((Typesymbol) root_symbol.scope.lookup ("bool"));
- string_type = new ClassType ((Class) root_symbol.scope.lookup ("string"));
+ string_type = new ClassInstanceType ((Class) root_symbol.scope.lookup ("string"));
int_type = new ValueType ((Typesymbol) root_symbol.scope.lookup ("int"));
uint_type = new ValueType ((Typesymbol) root_symbol.scope.lookup ("uint"));
type_type = new ValueType ((Typesymbol) glib_ns.scope.lookup ("Type"));
- glist_type = new ClassType ((Class) glib_ns.scope.lookup ("List"));
- gslist_type = new ClassType ((Class) glib_ns.scope.lookup ("SList"));
+ glist_type = new ClassInstanceType ((Class) glib_ns.scope.lookup ("List"));
+ gslist_type = new ClassInstanceType ((Class) glib_ns.scope.lookup ("SList"));
gerror_type = (Class) glib_ns.scope.lookup ("Error");
}
var gee_ns = root_symbol.scope.lookup ("Gee");
if (gee_ns != null) {
- iterable_type = new InterfaceType ((Interface) gee_ns.scope.lookup ("Iterable"));
+ iterable_type = new InterfaceInstanceType ((Interface) gee_ns.scope.lookup ("Iterable"));
iterator_type = (Interface) gee_ns.scope.lookup ("Iterator");
list_type = (Interface) gee_ns.scope.lookup ("List");
map_type = (Interface) gee_ns.scope.lookup ("Map");
public override void visit_field (Field f) {
f.accept_children (this);
- if (f.instance && f.parent_symbol is Interface) {
+ if (f.binding == MemberBinding.INSTANCE && f.parent_symbol is Interface) {
f.error = true;
Report.error (f.source_reference, "Interfaces may not have instance fields");
return;
public override void visit_property (Property prop) {
current_symbol = prop;
- if (!prop.instance) {
+ if (prop.binding != MemberBinding.INSTANCE) {
Report.error (prop.source_reference, "static properties are not yet supported");
prop.error = true;
return;
}
public override void visit_constructor (Constructor c) {
- c.this_parameter = new FormalParameter ("this", new ClassType (current_class));
+ c.this_parameter = new FormalParameter ("this", new ClassInstanceType (current_class));
c.scope.add (c.this_parameter.name, c.this_parameter);
c.owner = current_symbol.scope;
return;
}
field = field_it.get ();
- if (!field.instance) {
+ if (field.binding != MemberBinding.INSTANCE) {
// we only initialize instance fields
field = null;
}
need_type_check = true;
}
} else if (iterable_type != null && collection_type.compatible (iterable_type)) {
- var foreach_iterator_type = new InterfaceType (iterator_type);
+ var foreach_iterator_type = new InterfaceInstanceType (iterator_type);
foreach_iterator_type.takes_ownership = true;
foreach_iterator_type.add_type_argument (stmt.type_reference);
stmt.iterator_variable = new LocalVariable (foreach_iterator_type, "%s_it".printf (stmt.variable_name));
may_access_instance_members = true;
} else if (sym is Method) {
var m = (Method) sym;
- may_access_instance_members = m.instance;
+ may_access_instance_members = (m.binding == MemberBinding.INSTANCE);
}
expr.symbol_reference = symbol_lookup_inherited (sym, expr.member_name);
if (member is Field) {
var f = (Field) member;
access = f.access;
- instance = f.instance;
+ instance = (f.binding == MemberBinding.INSTANCE);
} else if (member is Method) {
var m = (Method) member;
access = m.access;
- instance = m.instance;
+ instance = (m.binding == MemberBinding.INSTANCE);
} else if (member is Property) {
var prop = (Property) member;
access = prop.access;
access = prop.get_accessor.access;
}
}
- instance = prop.instance;
+ instance = (prop.binding == MemberBinding.INSTANCE);
} else if (member is Signal) {
instance = true;
}
// construct a new type reference for the base type with correctly linked type arguments
ReferenceType instance_base_type;
if (base_type.data_type is Class) {
- instance_base_type = new ClassType ((Class) base_type.data_type);
+ instance_base_type = new ClassInstanceType ((Class) base_type.data_type);
} else {
- instance_base_type = new InterfaceType ((Interface) base_type.data_type);
+ instance_base_type = new InterfaceInstanceType ((Interface) base_type.data_type);
}
foreach (DataType type_arg in base_type.get_type_arguments ()) {
if (type_arg.type_parameter != null) {
return true;
} else if (sym is Method) {
var m = (Method) sym;
- return m.instance;
+ return m.binding == MemberBinding.INSTANCE;
} else if (sym is Constructor) {
var c = (Constructor) sym;
- return c.instance;
+ return c.binding == MemberBinding.INSTANCE;
} else if (sym is Destructor) {
return true;
} else if (sym is Property) {
Report.error (expr.source_reference, "Base access invalid without base class");
return;
} else {
- expr.static_type = new ClassType (current_class.base_class);
+ expr.static_type = new ClassInstanceType (current_class.base_class);
}
expr.symbol_reference = expr.static_type.data_type;
if (type_sym is Class) {
type = (Typesymbol) type_sym;
- expr.type_reference = new ClassType ((Class) type);
+ expr.type_reference = new ClassInstanceType ((Class) type);
} else if (type_sym is Struct) {
type = (Typesymbol) type_sym;
expr.type_reference = new ValueType (type);
return;
}
if (!(expr.inner.static_type is ValueType
- || expr.inner.static_type is ClassType
- || expr.inner.static_type is InterfaceType
+ || expr.inner.static_type is ClassInstanceType
+ || expr.inner.static_type is InterfaceInstanceType
|| expr.inner.static_type is PointerType)) {
expr.error = true;
Report.error (expr.source_reference, "Address-of operator not supported for this expression");
bool in_instance_method = false;
var current_method = find_current_method ();
if (current_method != null) {
- in_instance_method = current_method.instance;
+ in_instance_method = (current_method.binding == MemberBinding.INSTANCE);
} else {
in_instance_method = is_in_constructor ();
}
var cb = (Delegate) ((DelegateType) l.expected_type).delegate_symbol;
l.method = new Method (get_lambda_name (), cb.return_type);
- l.method.instance = cb.instance && in_instance_method;
+ if (!cb.has_target || !in_instance_method) {
+ l.method.binding = MemberBinding.STATIC;
+ }
l.method.owner = current_symbol.scope;
var lambda_params = l.get_parameters ();
// parent_symbol is null for D-Bus signals
if (generated_delegate == null && parent_symbol != null) {
generated_delegate = new Delegate (null, return_type);
- generated_delegate.instance = true;
+ generated_delegate.has_target = true;
ReferenceType sender_type;
if (parent_symbol is Class) {
- sender_type = new ClassType ((Class) parent_symbol);
+ sender_type = new ClassInstanceType ((Class) parent_symbol);
} else {
- sender_type = new InterfaceType ((Interface) parent_symbol);
+ sender_type = new InterfaceInstanceType ((Interface) parent_symbol);
}
var sender_param = new FormalParameter ("sender", sender_type);
generated_delegate.add_parameter (sender_param);
public void add_method (Method m) {
return_if_fail (m != null);
- if (m.instance) {
+ if (m.binding == MemberBinding.INSTANCE) {
m.this_parameter = new FormalParameter ("this", new ValueType (this));
m.scope.add (m.this_parameter.name, m.this_parameter);
}
if (cl.is_error_base) {
type = new ErrorType (null, unresolved_type.source_reference);
} else {
- type = new ClassType (cl);
+ type = new ClassInstanceType (cl);
}
} else if (sym is Interface) {
- type = new InterfaceType ((Interface) sym);
+ type = new InterfaceInstanceType ((Interface) sym);
} else if (sym is Struct) {
type = new ValueType ((Struct) sym);
} else if (sym is Enum) {
} else if (node.type == IdlNodeTypeId.FUNCTION) {
var m = parse_function ((IdlNodeFunction) node);
if (m != null) {
- m.instance = false;
+ m.binding = MemberBinding.STATIC;
ns.add_method (m);
current_source_file.add_node (m);
}
if (remaining_params == 1 && (param_node.name == "user_data" || param_node.name == "data")) {
// hide user_data parameter for instance delegates
- cb.instance = true;
+ cb.has_target = true;
} else {
string param_name = param_node.name;
if (param_name == "string") {
continue;
} else {
// static method
- m.instance = false;
+ m.binding = MemberBinding.STATIC;
}
}
if (first) {
// no parameters => static method
- m.instance = false;
+ m.binding = MemberBinding.STATIC;
}
if (last_param != null && last_param.name.has_prefix ("first_")) {
Method m = create_method (node.name, symbol, v.result, func != null ? func.parameters : v.parameters, false, is_interface);
if (m != null) {
- m.instance = true;
+ m.binding = MemberBinding.INSTANCE;
m.is_virtual = !is_interface;
m.is_abstract = is_interface;