vala r1695 - in trunk: . gobject vala
- From: rasa svn gnome org
- To: svn-commits-list gnome org
- Subject: vala r1695 - in trunk: . gobject vala
- Date: Fri, 11 Jul 2008 14:55:33 +0000 (UTC)
Author: rasa
Date: Fri Jul 11 14:55:33 2008
New Revision: 1695
URL: http://svn.gnome.org/viewvc/vala?rev=1695&view=rev
Log:
2008-07-11 Raffaele Sandrini <raffaele sandrini ch>
* gobject/valaccodemethodbinding.vala:
* vala/valamethod.vala:
Generate a type_real_name function also for abstract methods to warn
from buggy subclasses which fail to implement the abstract methods,
based on patch by Jared Moore, fixes bug 531195
Modified:
trunk/ChangeLog
trunk/gobject/valaccodemethodbinding.vala
trunk/vala/valamethod.vala
Modified: trunk/gobject/valaccodemethodbinding.vala
==============================================================================
--- trunk/gobject/valaccodemethodbinding.vala (original)
+++ trunk/gobject/valaccodemethodbinding.vala Fri Jul 11 14:55:33 2008
@@ -214,183 +214,203 @@
bool visible = !m.is_internal_symbol ();
- /* real function declaration and definition not needed
- * for abstract methods */
- if (!m.is_abstract) {
- if (visible && m.base_method == null && m.base_interface_method == null) {
- /* public methods need function declaration in
- * header file except virtual/overridden methods */
- codegen.header_type_member_declaration.append (codegen.function.copy ());
- } else {
- /* declare all other functions in source file to
- * avoid dependency on order within source file */
- codegen.function.modifiers |= CCodeModifiers.STATIC;
- codegen.source_type_member_declaration.append (codegen.function.copy ());
- }
-
- /* Methods imported from a plain C file don't
- * have a body, e.g. Vala.Parser.parse_file () */
- if (m.body != null) {
- codegen.function.block = (CCodeBlock) m.body.ccodenode;
- codegen.function.block.line = codegen.function.line;
-
- var cinit = new CCodeFragment ();
- codegen.function.block.prepend_statement (cinit);
+ if (visible && m.base_method == null && m.base_interface_method == null) {
+ /* public methods need function declaration in
+ * header file except virtual/overridden methods */
+ codegen.header_type_member_declaration.append (codegen.function.copy ());
+ } else {
+ /* declare all other functions in source file to
+ * avoid dependency on order within source file */
+ codegen.function.modifiers |= CCodeModifiers.STATIC;
+ codegen.source_type_member_declaration.append (codegen.function.copy ());
+ }
+
+ /* Methods imported from a plain C file don't
+ * have a body, e.g. Vala.Parser.parse_file () */
+ if (m.body != null) {
+ codegen.function.block = (CCodeBlock) m.body.ccodenode;
+ codegen.function.block.line = codegen.function.line;
- if (m.parent_symbol is Class) {
- var cl = (Class) m.parent_symbol;
- if (m.overrides || (m.base_interface_method != null && !m.is_abstract && !m.is_virtual)) {
- Method base_method;
- ReferenceType base_expression_type;
- if (m.overrides) {
- base_method = m.base_method;
- base_expression_type = new ObjectType ((Class) base_method.parent_symbol);
- } else {
- base_method = m.base_interface_method;
- base_expression_type = new ObjectType ((Interface) base_method.parent_symbol);
- }
- var self_target_type = new ObjectType (cl);
- CCodeExpression cself = codegen.transform_expression (new CCodeIdentifier ("base"), base_expression_type, self_target_type);
+ var cinit = new CCodeFragment ();
+ codegen.function.block.prepend_statement (cinit);
- var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
- cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", cself));
-
- cinit.append (cdecl);
- } 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);
+ if (m.parent_symbol is Class) {
+ var cl = (Class) m.parent_symbol;
+ if (m.overrides || (m.base_interface_method != null && !m.is_abstract && !m.is_virtual)) {
+ Method base_method;
+ ReferenceType base_expression_type;
+ if (m.overrides) {
+ base_method = m.base_method;
+ base_expression_type = new ObjectType ((Class) base_method.parent_symbol);
+ } else {
+ base_method = m.base_interface_method;
+ base_expression_type = new ObjectType ((Interface) base_method.parent_symbol);
}
+ var self_target_type = new ObjectType (cl);
+ CCodeExpression cself = codegen.transform_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.binding == MemberBinding.INSTANCE) {
+ var ccheckstmt = create_method_type_check_statement (m, creturn_type, cl, true, "self");
+ ccheckstmt.line = codegen.function.line;
+ cinit.append (ccheckstmt);
+ }
+ }
+ foreach (FormalParameter param in m.get_parameters ()) {
+ if (param.ellipsis) {
+ break;
}
- foreach (FormalParameter param in m.get_parameters ()) {
- if (param.ellipsis) {
- break;
- }
- var t = param.parameter_type.data_type;
- if (t != null && t.is_reference_type ()) {
- if (param.direction != ParameterDirection.OUT) {
- var type_check = create_method_type_check_statement (m, creturn_type, t, (codegen.context.non_null && !param.parameter_type.nullable), param.name);
- if (type_check != null) {
- type_check.line = codegen.function.line;
- cinit.append (type_check);
- }
- } else {
- // ensure that the passed reference for output parameter is cleared
- var a = new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (param.name)), new CCodeConstant ("NULL"));
- cinit.append (new CCodeExpressionStatement (a));
+ var t = param.parameter_type.data_type;
+ if (t != null && t.is_reference_type ()) {
+ if (param.direction != ParameterDirection.OUT) {
+ var type_check = create_method_type_check_statement (m, creturn_type, t, (codegen.context.non_null && !param.parameter_type.nullable), param.name);
+ if (type_check != null) {
+ type_check.line = codegen.function.line;
+ cinit.append (type_check);
}
+ } else {
+ // ensure that the passed reference for output parameter is cleared
+ var a = new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (param.name)), new CCodeConstant ("NULL"));
+ cinit.append (new CCodeExpressionStatement (a));
}
}
+ }
- if (inner_error) {
- /* always separate error parameter and inner_error local variable
- * as error may be set to NULL but we're always interested in inner errors
- */
- var cdecl = new CCodeDeclaration ("GError *");
- cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
- cinit.append (cdecl);
- }
-
- if (m.source_reference != null && m.source_reference.comment != null) {
- codegen.source_type_member_definition.append (new CCodeComment (m.source_reference.comment));
- }
- codegen.source_type_member_definition.append (codegen.function);
-
- if (m is CreationMethod) {
- if (in_gobject_creation_method) {
- int n_params = ((CreationMethod) m).n_construction_params;
-
- if (n_params > 0 || codegen.current_class.get_type_parameters ().size > 0) {
- // declare construction parameter array
- var cparamsinit = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
- cparamsinit.add_argument (new CCodeIdentifier ("GParameter"));
- cparamsinit.add_argument (new CCodeConstant ((n_params + 3 * codegen.current_class.get_type_parameters ().size).to_string ()));
-
- var cdecl = new CCodeDeclaration ("GParameter *");
- cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params", cparamsinit));
- cinit.append (cdecl);
-
- cdecl = new CCodeDeclaration ("GParameter *");
- cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params_it", new CCodeIdentifier ("__params")));
- cinit.append (cdecl);
- }
+ if (inner_error) {
+ /* always separate error parameter and inner_error local variable
+ * as error may be set to NULL but we're always interested in inner errors
+ */
+ var cdecl = new CCodeDeclaration ("GError *");
+ cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
+ cinit.append (cdecl);
+ }
- /* type, dup func, and destroy func properties for generic types */
- foreach (TypeParameter type_param in codegen.current_class.get_type_parameters ()) {
- CCodeConstant prop_name;
- CCodeIdentifier param_name;
-
- prop_name = new CCodeConstant ("\"%s-type\"".printf (type_param.name.down ()));
- param_name = new CCodeIdentifier ("%s_type".printf (type_param.name.down ()));
- cinit.append (new CCodeExpressionStatement (get_construct_property_assignment (prop_name, new ValueType (codegen.gtype_type), param_name)));
-
- prop_name = new CCodeConstant ("\"%s-dup-func\"".printf (type_param.name.down ()));
- param_name = new CCodeIdentifier ("%s_dup_func".printf (type_param.name.down ()));
- cinit.append (new CCodeExpressionStatement (get_construct_property_assignment (prop_name, new PointerType (new VoidType ()), param_name)));
-
- prop_name = new CCodeConstant ("\"%s-destroy-func\"".printf (type_param.name.down ()));
- param_name = new CCodeIdentifier ("%s_destroy_func".printf (type_param.name.down ()));
- cinit.append (new CCodeExpressionStatement (get_construct_property_assignment (prop_name, new PointerType (new VoidType ()), param_name)));
- }
- } else if (in_gtypeinstance_creation_method) {
- var cl = (Class) m.parent_symbol;
- var cdecl = new CCodeDeclaration (cl.get_cname () + "*");
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_create_instance"));
- ccall.add_argument (new CCodeIdentifier (cl.get_type_id ()));
- cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", new CCodeCastExpression (ccall, cl.get_cname () + "*")));
+ if (m.source_reference != null && m.source_reference.comment != null) {
+ codegen.source_type_member_definition.append (new CCodeComment (m.source_reference.comment));
+ }
+ codegen.source_type_member_definition.append (codegen.function);
+
+ if (m is CreationMethod) {
+ if (in_gobject_creation_method) {
+ int n_params = ((CreationMethod) m).n_construction_params;
+
+ if (n_params > 0 || codegen.current_class.get_type_parameters ().size > 0) {
+ // declare construction parameter array
+ var cparamsinit = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
+ cparamsinit.add_argument (new CCodeIdentifier ("GParameter"));
+ cparamsinit.add_argument (new CCodeConstant ((n_params + 3 * codegen.current_class.get_type_parameters ().size).to_string ()));
+
+ var cdecl = new CCodeDeclaration ("GParameter *");
+ cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params", cparamsinit));
cinit.append (cdecl);
-
- /* type, dup func, and destroy func fields for generic types */
- foreach (TypeParameter type_param in codegen.current_class.get_type_parameters ()) {
- CCodeIdentifier param_name;
- CCodeAssignment assign;
-
- var priv_access = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv");
-
- param_name = new CCodeIdentifier ("%s_type".printf (type_param.name.down ()));
- assign = new CCodeAssignment (new CCodeMemberAccess.pointer (priv_access, param_name.name), param_name);
- cinit.append (new CCodeExpressionStatement (assign));
-
- param_name = new CCodeIdentifier ("%s_dup_func".printf (type_param.name.down ()));
- assign = new CCodeAssignment (new CCodeMemberAccess.pointer (priv_access, param_name.name), param_name);
- cinit.append (new CCodeExpressionStatement (assign));
-
- param_name = new CCodeIdentifier ("%s_destroy_func".printf (type_param.name.down ()));
- assign = new CCodeAssignment (new CCodeMemberAccess.pointer (priv_access, param_name.name), param_name);
- cinit.append (new CCodeExpressionStatement (assign));
- }
- } else if (codegen.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));
+
+ cdecl = new CCodeDeclaration ("GParameter *");
+ cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params_it", new CCodeIdentifier ("__params")));
cinit.append (cdecl);
- } else {
- var st = (Struct) m.parent_symbol;
+ }
- // memset needs string.h
- codegen.string_h_needed = true;
- var czero = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
- czero.add_argument (new CCodeIdentifier ("self"));
- czero.add_argument (new CCodeConstant ("0"));
- czero.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (st.get_cname ())));
- cinit.append (new CCodeExpressionStatement (czero));
+ /* type, dup func, and destroy func properties for generic types */
+ foreach (TypeParameter type_param in codegen.current_class.get_type_parameters ()) {
+ CCodeConstant prop_name;
+ CCodeIdentifier param_name;
+
+ prop_name = new CCodeConstant ("\"%s-type\"".printf (type_param.name.down ()));
+ param_name = new CCodeIdentifier ("%s_type".printf (type_param.name.down ()));
+ cinit.append (new CCodeExpressionStatement (get_construct_property_assignment (prop_name, new ValueType (codegen.gtype_type), param_name)));
+
+ prop_name = new CCodeConstant ("\"%s-dup-func\"".printf (type_param.name.down ()));
+ param_name = new CCodeIdentifier ("%s_dup_func".printf (type_param.name.down ()));
+ cinit.append (new CCodeExpressionStatement (get_construct_property_assignment (prop_name, new PointerType (new VoidType ()), param_name)));
+
+ prop_name = new CCodeConstant ("\"%s-destroy-func\"".printf (type_param.name.down ()));
+ param_name = new CCodeIdentifier ("%s_destroy_func".printf (type_param.name.down ()));
+ cinit.append (new CCodeExpressionStatement (get_construct_property_assignment (prop_name, new PointerType (new VoidType ()), param_name)));
}
- }
+ } else if (in_gtypeinstance_creation_method) {
+ var cl = (Class) m.parent_symbol;
+ var cdecl = new CCodeDeclaration (cl.get_cname () + "*");
+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_create_instance"));
+ ccall.add_argument (new CCodeIdentifier (cl.get_type_id ()));
+ cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", new CCodeCastExpression (ccall, cl.get_cname () + "*")));
+ cinit.append (cdecl);
- if (codegen.context.module_init_method == m && codegen.in_plugin) {
- // GTypeModule-based plug-in, register types
- cinit.append (codegen.module_init_fragment);
- }
+ /* type, dup func, and destroy func fields for generic types */
+ foreach (TypeParameter type_param in codegen.current_class.get_type_parameters ()) {
+ CCodeIdentifier param_name;
+ CCodeAssignment assign;
+
+ var priv_access = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv");
+
+ param_name = new CCodeIdentifier ("%s_type".printf (type_param.name.down ()));
+ assign = new CCodeAssignment (new CCodeMemberAccess.pointer (priv_access, param_name.name), param_name);
+ cinit.append (new CCodeExpressionStatement (assign));
+
+ param_name = new CCodeIdentifier ("%s_dup_func".printf (type_param.name.down ()));
+ assign = new CCodeAssignment (new CCodeMemberAccess.pointer (priv_access, param_name.name), param_name);
+ cinit.append (new CCodeExpressionStatement (assign));
+
+ param_name = new CCodeIdentifier ("%s_destroy_func".printf (type_param.name.down ()));
+ assign = new CCodeAssignment (new CCodeMemberAccess.pointer (priv_access, param_name.name), param_name);
+ cinit.append (new CCodeExpressionStatement (assign));
+ }
+ } else if (codegen.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;
- foreach (Expression precondition in m.get_preconditions ()) {
- cinit.append (create_precondition_statement (m, creturn_type, precondition));
+ // memset needs string.h
+ codegen.string_h_needed = true;
+ var czero = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
+ czero.add_argument (new CCodeIdentifier ("self"));
+ czero.add_argument (new CCodeConstant ("0"));
+ czero.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (st.get_cname ())));
+ cinit.append (new CCodeExpressionStatement (czero));
}
}
+
+ if (codegen.context.module_init_method == m && codegen.in_plugin) {
+ // GTypeModule-based plug-in, register types
+ cinit.append (codegen.module_init_fragment);
+ }
+
+ foreach (Expression precondition in m.get_preconditions ()) {
+ cinit.append (create_precondition_statement (m, creturn_type, precondition));
+ }
+ } else if (m.is_abstract) {
+ // Generate stub function that prints out a helpful error message in case this
+ // method is not overwritten, see bug 531195
+
+ var cblock = new CCodeBlock ();
+
+ cblock.add_statement (create_method_type_check_statement (m, creturn_type, codegen.current_type_symbol, true, "self"));
+
+ var type_from_instance_call = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_INSTANCE"));
+ type_from_instance_call.add_argument (new CCodeIdentifier ("self"));
+
+ var type_name_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_name"));
+ type_name_call.add_argument (type_from_instance_call);
+
+ var error_string = "\"Type `%%s' does not implement abstract method `%s'\"".printf (m.get_cname ());
+
+ var cerrorcall = new CCodeFunctionCall (new CCodeIdentifier ("g_critical"));
+ cerrorcall.add_argument (new CCodeConstant (error_string));
+ cerrorcall.add_argument (type_name_call);
+
+ cblock.add_statement (new CCodeExpressionStatement (cerrorcall));
+
+ codegen.function.block = cblock;
+ codegen.source_type_member_definition.append (codegen.function);
}
-
+
if (m.is_abstract || m.is_virtual) {
var vfunc = new CCodeFunction (m.get_cname (), creturn_type.get_cname ());
vfunc.line = codegen.function.line;
Modified: trunk/vala/valamethod.vala
==============================================================================
--- trunk/vala/valamethod.vala (original)
+++ trunk/vala/valamethod.vala Fri Jul 11 14:55:33 2008
@@ -126,8 +126,8 @@
/**
* Specifies the virtual or abstract method this method overrides.
- * Reference must be weak as virtual methods set base_method to
- * themselves.
+ * Reference must be weak as virtual and abstract methods set
+ * base_method to themselves.
*/
public Method base_method {
get {
@@ -516,7 +516,7 @@
if (!parent_symbol.external_package) {
if (!(this is CreationMethod)) {
find_base_interface_method ((Class) parent_symbol);
- if (is_virtual || overrides) {
+ if (is_virtual || is_abstract || overrides) {
find_base_class_method ((Class) parent_symbol);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]