2007-08-30 Jürg Billeter <j@bitron.ch>
+ * vala/valaclass.vala, vala/valasemanticanalyzer.vala,
+ gobject/valacodegenerator.vala, gobject/valacodegeneratorclass.vala,
+ gobject/valacodegeneratormethod.vala, vapi/glib-2.0.vala: support
+ classes without base class
+
+2007-08-30 Jürg Billeter <j@bitron.ch>
+
* vala/valasymbolresolver.vala, vala/valasemanticanalyzer.vala,
gobject/valacodegenerator.vala, gobject/valacodegeneratorclass.vala:
don't implicitly derive from GLib.Object in preparation for a more
var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, cvar, new CCodeConstant ("NULL"));
if (type.data_type == null) {
- if (!(current_type_symbol is Class)) {
+ if (!(current_type_symbol is Class) || !current_class.is_subtype_of (gobject_type)) {
return new CCodeConstant ("NULL");
}
var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ()));
- if (expr.type_reference.data_type is Class) {
+ if (expr.type_reference.data_type is Class && expr.type_reference.data_type.is_subtype_of (gobject_type)) {
foreach (TypeReference type_arg in expr.type_reference.get_type_arguments ()) {
if (type_arg.takes_ownership) {
ccall.add_argument (get_dup_func_expression (type_arg));
current_symbol = cl;
current_type_symbol = cl;
current_class = cl;
+
+ bool is_gobject = cl.is_subtype_of (gobject_type);
if (cl.get_cname().len () < 3) {
cl.error = true;
decl_frag = source_type_member_declaration;
def_frag = source_type_member_declaration;
}
-
- decl_frag.append (new CCodeNewline ());
+
var macro = "(%s_get_type ())".printf (cl.get_lower_case_cname (null));
- decl_frag.append (new CCodeMacroReplacement (cl.get_upper_case_cname ("TYPE_"), macro));
+ if (is_gobject) {
+ decl_frag.append (new CCodeNewline ());
+ decl_frag.append (new CCodeMacroReplacement (cl.get_upper_case_cname ("TYPE_"), macro));
- macro = "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
- decl_frag.append (new CCodeMacroReplacement ("%s(obj)".printf (cl.get_upper_case_cname (null)), macro));
+ macro = "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
+ decl_frag.append (new CCodeMacroReplacement ("%s(obj)".printf (cl.get_upper_case_cname (null)), macro));
- macro = "(G_TYPE_CHECK_CLASS_CAST ((klass), %s, %sClass))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
- decl_frag.append (new CCodeMacroReplacement ("%s_CLASS(klass)".printf (cl.get_upper_case_cname (null)), macro));
+ macro = "(G_TYPE_CHECK_CLASS_CAST ((klass), %s, %sClass))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
+ decl_frag.append (new CCodeMacroReplacement ("%s_CLASS(klass)".printf (cl.get_upper_case_cname (null)), macro));
- macro = "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (cl.get_upper_case_cname ("TYPE_"));
- decl_frag.append (new CCodeMacroReplacement ("%s(obj)".printf (cl.get_upper_case_cname ("IS_")), macro));
+ macro = "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (cl.get_upper_case_cname ("TYPE_"));
+ decl_frag.append (new CCodeMacroReplacement ("%s(obj)".printf (cl.get_upper_case_cname ("IS_")), macro));
- macro = "(G_TYPE_CHECK_CLASS_TYPE ((klass), %s))".printf (cl.get_upper_case_cname ("TYPE_"));
- decl_frag.append (new CCodeMacroReplacement ("%s_CLASS(klass)".printf (cl.get_upper_case_cname ("IS_")), macro));
+ macro = "(G_TYPE_CHECK_CLASS_TYPE ((klass), %s))".printf (cl.get_upper_case_cname ("TYPE_"));
+ decl_frag.append (new CCodeMacroReplacement ("%s_CLASS(klass)".printf (cl.get_upper_case_cname ("IS_")), macro));
- macro = "(G_TYPE_INSTANCE_GET_CLASS ((obj), %s, %sClass))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
- decl_frag.append (new CCodeMacroReplacement ("%s_GET_CLASS(obj)".printf (cl.get_upper_case_cname (null)), macro));
- decl_frag.append (new CCodeNewline ());
+ macro = "(G_TYPE_INSTANCE_GET_CLASS ((obj), %s, %sClass))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
+ decl_frag.append (new CCodeMacroReplacement ("%s_GET_CLASS(obj)".printf (cl.get_upper_case_cname (null)), macro));
+ decl_frag.append (new CCodeNewline ());
+ }
if (cl.source_reference.file.cycle == null) {
decl_frag.append (new CCodeTypeDefinition ("struct %s".printf (instance_struct.name), new CCodeVariableDeclarator (cl.get_cname ())));
- decl_frag.append (new CCodeTypeDefinition ("struct %s".printf (type_struct.name), new CCodeVariableDeclarator ("%sClass".printf (cl.get_cname ()))));
}
- decl_frag.append (new CCodeTypeDefinition ("struct %s".printf (instance_priv_struct.name), new CCodeVariableDeclarator ("%sPrivate".printf (cl.get_cname ()))));
- if (cl.is_subtype_of (gobject_type)) {
+ if (is_gobject) {
+ if (cl.source_reference.file.cycle == null) {
+ decl_frag.append (new CCodeTypeDefinition ("struct %s".printf (type_struct.name), new CCodeVariableDeclarator ("%sClass".printf (cl.get_cname ()))));
+ }
+ decl_frag.append (new CCodeTypeDefinition ("struct %s".printf (instance_priv_struct.name), new CCodeVariableDeclarator ("%sPrivate".printf (cl.get_cname ()))));
+
instance_struct.add_field (cl.base_class.get_cname (), "parent");
instance_struct.add_field ("%sPrivate *".printf (cl.get_cname ()), "priv");
type_struct.add_field ("%sClass".printf (cl.base_class.get_cname ()), "parent");
def_frag.append (new CCodeComment (cl.source_reference.comment));
}
def_frag.append (instance_struct);
- def_frag.append (type_struct);
- /* only add the *Private struct if it is not empty, i.e. we actually have private data */
- if (cl.has_private_fields || cl.get_type_parameters ().size > 0) {
- source_type_member_declaration.append (instance_priv_struct);
- macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
- source_type_member_declaration.append (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), macro));
+
+ if (is_gobject) {
+ def_frag.append (type_struct);
+ /* only add the *Private struct if it is not empty, i.e. we actually have private data */
+ if (cl.has_private_fields || cl.get_type_parameters ().size > 0) {
+ source_type_member_declaration.append (instance_priv_struct);
+ macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
+ source_type_member_declaration.append (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), macro));
+ }
+ source_type_member_declaration.append (prop_enum);
}
- source_type_member_declaration.append (prop_enum);
cl.accept_children (this);
- if (cl.is_subtype_of (gobject_type)) {
+ if (is_gobject) {
if (class_has_readable_properties (cl) || cl.get_type_parameters ().size > 0) {
add_get_property_function (cl);
}
register_call.add_argument (new CCodeIdentifier (module_init_param_name));
module_init_fragment.append (new CCodeExpressionStatement (register_call));
}
+ } else if (cl.default_construction_method != null) {
+ var function = new CCodeFunction (cl.get_lower_case_cprefix () + "free", "void");
+ if (cl.access == MemberAccessibility.PRIVATE) {
+ function.modifiers = CCodeModifiers.STATIC;
+ }
+
+ function.add_parameter (new CCodeFormalParameter ("self", cl.get_cname () + "*"));
+
+ decl_frag.append (function.copy ());
+
+ var cblock = new CCodeBlock ();
+
+ cblock.add_statement (instance_dispose_fragment);
+
+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
+ ccall.add_argument (new CCodeIdentifier (cl.get_cname ()));
+ ccall.add_argument (new CCodeIdentifier ("self"));
+ cblock.add_statement (new CCodeExpressionStatement (ccall));
+
+ function.block = cblock;
+
+ def_frag.append (function);
}
current_type_symbol = old_type_symbol;
m.accept_children (this);
if (m is CreationMethod) {
- if (current_type_symbol is Class && m.body != null) {
+ if (current_type_symbol is Class && current_class.is_subtype_of (gobject_type) && m.body != null) {
var cblock = new CCodeBlock ();
foreach (CodeNode stmt in m.body.get_statements ()) {
}
}
- if (m is CreationMethod && current_type_symbol is Class) {
+ if (m is CreationMethod && current_type_symbol is Class && current_class.is_subtype_of (gobject_type)) {
// memory management for generic types
foreach (TypeParameter type_param in current_class.get_type_parameters ()) {
function.add_parameter (new CCodeFormalParameter ("%s_dup_func".printf (type_param.name.down ()), "GBoxedCopyFunc"));
source_type_member_definition.append (function);
if (m is CreationMethod) {
- if (current_type_symbol is Class) {
+ if (current_type_symbol is Class && current_class.is_subtype_of (gobject_type)) {
int n_params = ((CreationMethod) m).n_construction_params;
if (n_params > 0) {
cassign = new CCodeAssignment (cmember, new CCodeIdentifier (func_name));
function.block.add_statement (new CCodeExpressionStatement (cassign));
}
+ } else if (current_type_symbol is Class) {
+ var cl = (Class) m.parent_symbol;
+ var cdecl = new CCodeDeclaration (cl.get_cname () + "*");
+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0"));
+ ccall.add_argument (new CCodeIdentifier (cl.get_cname ()));
+ cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
+ cinit.append (cdecl);
} else {
var st = (Struct) m.parent_symbol;
var cdecl = new CCodeDeclaration (st.get_cname () + "*");
}
public override void visit_creation_method (CreationMethod! m) {
+ if (m.body != null && current_type_symbol is Class && current_class.is_subtype_of (gobject_type)) {
+ int n_params = 0;
+ foreach (Statement stmt in m.body.get_statements ()) {
+ if (!(stmt is ExpressionStatement) || ((ExpressionStatement) stmt).assigned_property () == null) {
+ m.error = true;
+ Report.error (stmt.source_reference, "class creation methods only allow property assignment statements");
+ return;
+ }
+ if (((ExpressionStatement) stmt).assigned_property ().set_accessor.construction) {
+ n_params++;
+ }
+ }
+ m.n_construction_params = n_params;
+ }
+
visit_method (m);
}
if (a.has_argument ("ctype")) {
if (a.get_string ("ctype") != "gobject") {
is_gobject = false;
- if (a.has_argument ("ref_function")) {
- set_ref_function (a.get_string ("ref_function"));
- }
- if (a.has_argument ("unref_function")) {
- set_unref_function (a.get_string ("unref_function"));
- }
- if (a.has_argument ("copy_function")) {
- set_dup_function (a.get_string ("copy_function"));
- }
- if (a.has_argument ("free_function")) {
- set_free_function (a.get_string ("free_function"));
- }
- if (a.has_argument ("type_id")) {
- type_id = a.get_string ("type_id");
- }
- if (a.has_argument ("marshaller_type_name")) {
- marshaller_type_name = a.get_string ("marshaller_type_name");
- }
- if (a.has_argument ("get_value_function")) {
- get_value_function = a.get_string ("get_value_function");
- }
- if (a.has_argument ("set_value_function")) {
- set_value_function = a.get_string ("set_value_function");
- }
}
}
+ if (a.has_argument ("ref_function")) {
+ set_ref_function (a.get_string ("ref_function"));
+ }
+ if (a.has_argument ("unref_function")) {
+ set_unref_function (a.get_string ("unref_function"));
+ }
+ if (a.has_argument ("copy_function")) {
+ set_dup_function (a.get_string ("copy_function"));
+ }
+ if (a.has_argument ("free_function")) {
+ set_free_function (a.get_string ("free_function"));
+ }
+ if (a.has_argument ("type_id")) {
+ type_id = a.get_string ("type_id");
+ }
+ if (a.has_argument ("marshaller_type_name")) {
+ marshaller_type_name = a.get_string ("marshaller_type_name");
+ }
+ if (a.has_argument ("get_value_function")) {
+ get_value_function = a.get_string ("get_value_function");
+ }
+ if (a.has_argument ("set_value_function")) {
+ set_value_function = a.get_string ("set_value_function");
+ }
+
if (a.has_argument ("cname")) {
set_cname (a.get_string ("cname"));
}
}
public override bool is_reference_counting () {
- return is_gobject || (ref_function != null && unref_function != null);
+ return get_ref_function () != null;
}
public override string get_ref_function () {
- if (is_gobject) {
- return "g_object_ref";
+ if (ref_function == null && base_class != null) {
+ return base_class.get_ref_function ();
} else {
return ref_function;
}
}
public override string get_unref_function () {
- if (is_gobject) {
- return "g_object_unref";
+ if (unref_function == null && base_class != null) {
+ return base_class.get_unref_function ();
} else {
return unref_function;
}
Report.error (m.source_reference, "The creation method `%s' cannot be marked as override, virtual, or abstract".printf (m.get_full_name ()));
return;
}
-
- if (m.body != null && current_class != null) {
- int n_params = 0;
- foreach (Statement stmt in m.body.get_statements ()) {
- if (!(stmt is ExpressionStatement) || ((ExpressionStatement) stmt).assigned_property () == null) {
- m.error = true;
- Report.error (stmt.source_reference, "class creation methods only allow property assignment statements");
- return;
- }
- if (((ExpressionStatement) stmt).assigned_property ().set_accessor.construction) {
- n_params++;
- }
- }
- m.n_construction_params = n_params;
- }
}
public override void visit_formal_parameter (FormalParameter! p) {
public static delegate void ObjectGetPropertyFunc (Object object, uint property_id, Value value, ParamSpec pspec);
public static delegate void ObjectSetPropertyFunc (Object object, uint property_id, Value value, ParamSpec pspec);
- [CCode (cheader_filename = "glib-object.h")]
+ [CCode (ref_function = "g_object_ref", unref_function = "g_object_unref", cheader_filename = "glib-object.h")]
public class Object {
[CCode (cname = "G_TYPE_FROM_INSTANCE")]
public Type get_type ();