From cc3fbb7965901741087eaac0990bafd8132eca37 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=BCrg=20Billeter?= Date: Fri, 16 Jul 2010 09:02:58 +0200 Subject: [PATCH] dova: Drop checked exceptions Replace error parameter by global variable. --- codegen/valadovabasemodule.vala | 13 ----- codegen/valadovaerrormodule.vala | 41 +++++++-------- codegen/valadovamethodcallmodule.vala | 7 --- codegen/valadovaobjectmodule.vala | 45 ----------------- vala/valacodewriter.vala | 5 +- vala/valamethod.vala | 2 +- vala/valamethodcall.vala | 6 ++- vala/valaobjectcreationexpression.vala | 6 ++- vala/valaparser.vala | 70 +++++++++++++++++++------- vala/valapropertyaccessor.vala | 10 ++-- 10 files changed, 89 insertions(+), 116 deletions(-) diff --git a/codegen/valadovabasemodule.vala b/codegen/valadovabasemodule.vala index 8db548811..99dd576d5 100644 --- a/codegen/valadovabasemodule.vala +++ b/codegen/valadovabasemodule.vala @@ -136,7 +136,6 @@ internal class Vala.DovaBaseModule : CCodeModule { public int next_temp_var_id = 0; public int next_wrapper_id = 0; public bool in_creation_method { get { return current_method is CreationMethod; } } - public bool current_method_inner_error = false; int next_block_id = 0; Map block_map = new HashMap (); @@ -208,7 +207,6 @@ internal class Vala.DovaBaseModule : CCodeModule { reserved_identifiers.add ("while"); // reserved for Vala naming conventions - reserved_identifiers.add ("error"); reserved_identifiers.add ("result"); reserved_identifiers.add ("this"); } @@ -659,9 +657,6 @@ internal class Vala.DovaBaseModule : CCodeModule { } public override void visit_destructor (Destructor d) { - bool old_method_inner_error = current_method_inner_error; - current_method_inner_error = false; - d.accept_children (codegen); CCodeFragment cfrag = new CCodeFragment (); @@ -669,8 +664,6 @@ internal class Vala.DovaBaseModule : CCodeModule { cfrag.append (d.body.ccodenode); d.ccodenode = cfrag; - - current_method_inner_error = old_method_inner_error; } public int get_block_id (Block b) { @@ -1856,12 +1849,6 @@ internal class Vala.DovaBaseModule : CCodeModule { creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance)); } - if (expr.tree_can_fail) { - // method can fail - current_method_inner_error = true; - creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_inner_error_"))); - } - if (ellipsis) { /* ensure variable argument list ends with NULL * except when using printf-style arguments */ diff --git a/codegen/valadovaerrormodule.vala b/codegen/valadovaerrormodule.vala index a422cfcd5..13c693607 100644 --- a/codegen/valadovaerrormodule.vala +++ b/codegen/valadovaerrormodule.vala @@ -38,8 +38,7 @@ internal class Vala.DovaErrorModule : DovaDelegateModule { var cfrag = new CCodeFragment (); // method will fail - current_method_inner_error = true; - var cassign = new CCodeAssignment (get_variable_cexpression ("_inner_error_"), (CCodeExpression) stmt.error_expression.ccodenode); + var cassign = new CCodeAssignment (new CCodeIdentifier ("dova_error"), (CCodeExpression) stmt.error_expression.ccodenode); cfrag.append (new CCodeExpressionStatement (cassign)); head.add_simple_check (stmt, cfrag, true); @@ -50,17 +49,17 @@ internal class Vala.DovaErrorModule : DovaDelegateModule { } public virtual CCodeStatement return_with_exception () { - // propagate error var cerror_block = new CCodeBlock (); - cerror_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("error")), get_variable_cexpression ("_inner_error_")))); - cerror_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression ("_inner_error_"), new CCodeConstant ("NULL")))); + + // propagate error + // nothing to do // free local variables var free_frag = new CCodeFragment (); append_local_free (current_symbol, free_frag, false); cerror_block.add_statement (free_frag); - if (current_method is CreationMethod) { + if (current_method is CreationMethod && current_method.parent_symbol is Class) { var cl = current_method.parent_symbol as Class; var unref_call = new CCodeFunctionCall (new CCodeIdentifier (cl.get_unref_function ())); unref_call.add_argument (new CCodeIdentifier ("this")); @@ -75,7 +74,7 @@ internal class Vala.DovaErrorModule : DovaDelegateModule { return cerror_block; } - CCodeStatement uncaught_error_statement (CCodeExpression inner_error, CCodeBlock? block = null, bool unexpected = false) { + CCodeStatement uncaught_error_statement (CCodeBlock? block = null, bool unexpected = false) { var cerror_block = block; if (cerror_block == null) { cerror_block = new CCodeBlock (); @@ -112,10 +111,6 @@ internal class Vala.DovaErrorModule : DovaDelegateModule { } public override void add_simple_check (CodeNode node, CCodeFragment cfrag, bool always_fails = false) { - current_method_inner_error = true; - - var inner_error = get_variable_cexpression ("_inner_error_"); - CCodeStatement cerror_handler = null; if (current_try != null) { @@ -161,8 +156,8 @@ internal class Vala.DovaErrorModule : DovaDelegateModule { var cgoto_block = new CCodeBlock (); cgoto_block.add_statement (cgoto_stmt); - var type_check = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_is_a")); - type_check.add_argument (inner_error); + var type_check = new CCodeFunctionCall (new CCodeIdentifier ("any_is_a")); + type_check.add_argument (new CCodeIdentifier ("dova_error")); type_check.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (catch_type.type_symbol.get_lower_case_cname ())))); cerror_block.add_statement (new CCodeIfStatement (type_check, cgoto_block)); @@ -183,7 +178,7 @@ internal class Vala.DovaErrorModule : DovaDelegateModule { // as jump out of finally block is not supported } else { // should never happen with correct bindings - uncaught_error_statement (inner_error, cerror_block, true); + uncaught_error_statement (cerror_block, true); } cerror_handler = cerror_block; @@ -199,8 +194,8 @@ internal class Vala.DovaErrorModule : DovaDelegateModule { } // Check the allowed error domains to propagate - var type_check = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_is_a")); - type_check.add_argument (inner_error); + var type_check = new CCodeFunctionCall (new CCodeIdentifier ("any_is_a")); + type_check.add_argument (new CCodeIdentifier ("dova_error")); type_check.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (error_class.get_lower_case_cname ())))); if (ccond == null) { ccond = type_check; @@ -215,11 +210,11 @@ internal class Vala.DovaErrorModule : DovaDelegateModule { var cerror_block = new CCodeBlock (); cerror_block.add_statement (new CCodeIfStatement (ccond, return_with_exception (), - uncaught_error_statement (inner_error))); + uncaught_error_statement ())); cerror_handler = cerror_block; } } else { - cerror_handler = uncaught_error_statement (inner_error); + cerror_handler = uncaught_error_statement (); } if (always_fails) { @@ -227,7 +222,7 @@ internal class Vala.DovaErrorModule : DovaDelegateModule { // eliminates C warnings cfrag.append (cerror_handler); } else { - var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, inner_error, new CCodeConstant ("NULL")); + var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("dova_error"), new CCodeConstant ("NULL")); cfrag.append (new CCodeIfStatement (ccond, cerror_handler)); } } @@ -287,8 +282,6 @@ internal class Vala.DovaErrorModule : DovaDelegateModule { clause.error_variable.active = true; } - current_method_inner_error = true; - generate_type_declaration (clause.error_type, source_declarations); clause.accept_children (codegen); @@ -307,15 +300,15 @@ internal class Vala.DovaErrorModule : DovaDelegateModule { if (clause.variable_name != null) { var cdecl = new CCodeDeclaration (clause.error_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator (variable_name, get_variable_cexpression ("_inner_error_"))); + cdecl.add_declarator (new CCodeVariableDeclarator (variable_name, new CCodeIdentifier ("dova_error"))); cblock.add_statement (cdecl); } else { // error object is not used within catch statement, clear it var cclear = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_unref")); - cclear.add_argument (get_variable_cexpression ("_inner_error_")); + cclear.add_argument (new CCodeIdentifier ("dova_error")); cblock.add_statement (new CCodeExpressionStatement (cclear)); } - cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression ("_inner_error_"), new CCodeConstant ("NULL")))); + cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("dova_error"), new CCodeConstant ("NULL")))); cblock.add_statement (clause.body.ccodenode); diff --git a/codegen/valadovamethodcallmodule.vala b/codegen/valadovamethodcallmodule.vala index a17b84a7c..149bc89a2 100644 --- a/codegen/valadovamethodcallmodule.vala +++ b/codegen/valadovamethodcallmodule.vala @@ -224,13 +224,6 @@ internal class Vala.DovaMethodCallModule : DovaAssignmentModule { ccall_expr = ccomma; } - if (expr.tree_can_fail) { - // method can fail - current_method_inner_error = true; - // add &inner_error before the ellipsis arguments - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression ("_inner_error_"))); - } - expr.ccodenode = ccall_expr; } } diff --git a/codegen/valadovaobjectmodule.vala b/codegen/valadovaobjectmodule.vala index d023792e1..817555e5c 100644 --- a/codegen/valadovaobjectmodule.vala +++ b/codegen/valadovaobjectmodule.vala @@ -1077,9 +1077,7 @@ internal class Vala.DovaObjectModule : DovaArrayModule { public override void visit_property_accessor (PropertyAccessor acc) { var old_symbol = current_symbol; - bool old_method_inner_error = current_method_inner_error; current_symbol = acc; - current_method_inner_error = false; var prop = (Property) acc.prop; @@ -1199,7 +1197,6 @@ internal class Vala.DovaObjectModule : DovaArrayModule { } current_symbol = old_symbol; - current_method_inner_error = old_method_inner_error; } public override void generate_interface_declaration (Interface iface, CCodeDeclarationSpace decl_space) { @@ -1281,9 +1278,6 @@ internal class Vala.DovaObjectModule : DovaArrayModule { if (m.return_type is GenericType) { param_list += ", void *"; } - if (m.get_error_types ().size > 0) { - param_list += ", DovaError **"; - } param_list += ")"; var override_func = new CCodeFunction ("%soverride_%s".printf (m.parent_symbol.get_lower_case_cprefix (), m.name)); @@ -1314,14 +1308,12 @@ internal class Vala.DovaObjectModule : DovaArrayModule { public override void visit_method (Method m) { var old_symbol = current_symbol; - bool old_method_inner_error = current_method_inner_error; int old_next_temp_var_id = next_temp_var_id; var old_temp_vars = temp_vars; var old_temp_ref_vars = temp_ref_vars; var old_variable_name_map = variable_name_map; var old_try = current_try; current_symbol = m; - current_method_inner_error = false; next_temp_var_id = 0; temp_vars = new ArrayList (); temp_ref_vars = new ArrayList (); @@ -1330,10 +1322,7 @@ internal class Vala.DovaObjectModule : DovaArrayModule { m.accept_children (codegen); - bool inner_error = current_method_inner_error; - current_symbol = old_symbol; - current_method_inner_error = old_method_inner_error; next_temp_var_id = old_next_temp_var_id; temp_vars = old_temp_vars; temp_ref_vars = old_temp_ref_vars; @@ -1432,12 +1421,6 @@ internal class Vala.DovaObjectModule : DovaArrayModule { function.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result"))); } - if (inner_error) { - var cdecl = new CCodeDeclaration ("DovaError *"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_inner_error_", new CCodeConstant ("NULL"))); - cinit.append (cdecl); - } - var st = m.parent_symbol as Struct; if (m is CreationMethod && st != null && (st.is_boolean_type () || st.is_integer_type () || st.is_floating_type ())) { var cdecl = new CCodeDeclaration (st.get_cname ()); @@ -1471,10 +1454,6 @@ internal class Vala.DovaObjectModule : DovaArrayModule { if (m.return_type is GenericType) { vfunc.add_parameter (new CCodeFormalParameter ("result", "void *")); } - if (m.get_error_types ().size > 0) { - var cparam = new CCodeFormalParameter ("error", "DovaError**"); - vfunc.add_parameter (cparam); - } var vcast = get_type_private_from_type ((ObjectTypeSymbol) m.parent_symbol, get_type_from_instance (new CCodeIdentifier ("this"))); @@ -1489,9 +1468,6 @@ internal class Vala.DovaObjectModule : DovaArrayModule { if (m.return_type is GenericType) { vcall.add_argument (new CCodeIdentifier ("result")); } - if (m.get_error_types ().size > 0) { - vcall.add_argument (new CCodeIdentifier ("error")); - } if (m.return_type is VoidType || m.return_type is GenericType) { vfunc.block.add_statement (new CCodeExpressionStatement (vcall)); @@ -1520,10 +1496,6 @@ internal class Vala.DovaObjectModule : DovaArrayModule { if (m.return_type is GenericType) { vfunc.add_parameter (new CCodeFormalParameter ("result", "void *")); } - if (m.get_error_types ().size > 0) { - var cparam = new CCodeFormalParameter ("error", "DovaError**"); - vfunc.add_parameter (cparam); - } var base_type = new CCodeIdentifier ("base_type"); @@ -1540,9 +1512,6 @@ internal class Vala.DovaObjectModule : DovaArrayModule { if (m.return_type is GenericType) { vcall.add_argument (new CCodeIdentifier ("result")); } - if (m.get_error_types ().size > 0) { - vcall.add_argument (new CCodeIdentifier ("error")); - } if (m.return_type is VoidType || m.return_type is GenericType) { vfunc.block.add_statement (new CCodeExpressionStatement (vcall)); @@ -1561,9 +1530,6 @@ internal class Vala.DovaObjectModule : DovaArrayModule { if (m.return_type is GenericType) { param_list += ", void *"; } - if (m.get_error_types ().size > 0) { - param_list += ", DovaError **"; - } param_list += ")"; var override_func = new CCodeFunction ("%soverride_%s".printf (m.parent_symbol.get_lower_case_cprefix (), m.name)); @@ -1859,17 +1825,6 @@ internal class Vala.DovaObjectModule : DovaArrayModule { generate_type_declaration (m.return_type, decl_space); } - - if (m.get_error_types ().size > 0 || (m.base_method != null && m.base_method.get_error_types ().size > 0)) { - var cparam = new CCodeFormalParameter ("error", "DovaError**"); - func.add_parameter (cparam); - if (vdeclarator != null) { - vdeclarator.add_parameter (cparam); - } - if (vcall != null) { - vcall.add_argument (new CCodeIdentifier ("error")); - } - } } public override void visit_element_access (ElementAccess expr) { diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala index 57209cd43..721ce3f61 100644 --- a/vala/valacodewriter.vala +++ b/vala/valacodewriter.vala @@ -1075,7 +1075,10 @@ public class Vala.CodeWriter : CodeVisitor { } write_params (m.get_parameters ()); - write_error_domains (m.get_error_types ()); + + if (context.profile != Profile.DOVA) { + write_error_domains (m.get_error_types ()); + } write_code_block (m.body); diff --git a/vala/valamethod.vala b/vala/valamethod.vala index 8b75efd75..0319868ac 100644 --- a/vala/valamethod.vala +++ b/vala/valamethod.vala @@ -939,7 +939,7 @@ public class Vala.Method : Member { entry_point = true; analyzer.context.entry_point = this; - if (tree_can_fail) { + if (tree_can_fail && analyzer.context.profile != Profile.DOVA) { Report.error (source_reference, "\"main\" method cannot throw errors"); } } diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala index f4fa66cd9..4da68f7e8 100644 --- a/vala/valamethodcall.vala +++ b/vala/valamethodcall.vala @@ -669,8 +669,10 @@ public class Vala.MethodCall : Expression { if (parent_node is LocalVariable || parent_node is ExpressionStatement) { // simple statements, no side effects after method call } else if (!(analyzer.current_symbol is Block)) { - // can't handle errors in field initializers - Report.error (source_reference, "Field initializers must not throw errors"); + if (analyzer.context.profile != Profile.DOVA) { + // can't handle errors in field initializers + Report.error (source_reference, "Field initializers must not throw errors"); + } } else { // store parent_node as we need to replace the expression in the old parent node later on var old_parent_node = parent_node; diff --git a/vala/valaobjectcreationexpression.vala b/vala/valaobjectcreationexpression.vala index ab726e79f..8e334fe47 100644 --- a/vala/valaobjectcreationexpression.vala +++ b/vala/valaobjectcreationexpression.vala @@ -392,8 +392,10 @@ public class Vala.ObjectCreationExpression : Expression { if (parent_node is LocalVariable || parent_node is ExpressionStatement) { // simple statements, no side effects after method call } else if (!(analyzer.current_symbol is Block)) { - // can't handle errors in field initializers - Report.error (source_reference, "Field initializers must not throw errors"); + if (analyzer.context.profile != Profile.DOVA) { + // can't handle errors in field initializers + Report.error (source_reference, "Field initializers must not throw errors"); + } } else { // store parent_node as we need to replace the expression in the old parent node later on var old_parent_node = parent_node; diff --git a/vala/valaparser.vala b/vala/valaparser.vala index 78aecc524..67366dfe5 100644 --- a/vala/valaparser.vala +++ b/vala/valaparser.vala @@ -2650,10 +2650,21 @@ public class Vala.Parser : CodeVisitor { } while (accept (TokenType.COMMA)); } expect (TokenType.CLOSE_PARENS); - if (accept (TokenType.THROWS)) { - do { - method.add_error_type (parse_type (true, false)); - } while (accept (TokenType.COMMA)); + if (context.profile == Profile.DOVA) { + var error_type = new UnresolvedType.from_symbol (new UnresolvedSymbol (new UnresolvedSymbol (null, "Dova"), "Error"), method.source_reference); + method.add_error_type (error_type); + if (accept (TokenType.THROWS)) { + do { + parse_type (true, false); + } while (accept (TokenType.COMMA)); + Report.warning (method.source_reference, "`throws' is ignored in the Dova profile"); + } + } else { + if (accept (TokenType.THROWS)) { + do { + method.add_error_type (parse_type (true, false)); + } while (accept (TokenType.COMMA)); + } } while (accept (TokenType.REQUIRES)) { expect (TokenType.OPEN_PARENS); @@ -2716,11 +2727,14 @@ public class Vala.Parser : CodeVisitor { if (ModifierFlags.EXTERN in flags || scanner.source_file.external_package) { prop.external = true; } - if (accept (TokenType.THROWS)) { - do { - prop.add_error_type (parse_type (true, false)); - } while (accept (TokenType.COMMA)); - Report.error (prop.source_reference, "properties throwing errors are not supported yet"); + if (context.profile == Profile.DOVA) { + } else { + if (accept (TokenType.THROWS)) { + do { + prop.add_error_type (parse_type (true, false)); + } while (accept (TokenType.COMMA)); + Report.error (prop.source_reference, "properties throwing errors are not supported yet"); + } } expect (TokenType.OPEN_BRACE); while (current () != TokenType.CLOSE_BRACE) { @@ -3300,10 +3314,21 @@ public class Vala.Parser : CodeVisitor { } while (accept (TokenType.COMMA)); } expect (TokenType.CLOSE_PARENS); - if (accept (TokenType.THROWS)) { - do { - method.add_error_type (parse_type (true, false)); - } while (accept (TokenType.COMMA)); + if (context.profile == Profile.DOVA) { + var error_type = new UnresolvedType.from_symbol (new UnresolvedSymbol (new UnresolvedSymbol (null, "Dova"), "Error"), method.source_reference); + method.add_error_type (error_type); + if (accept (TokenType.THROWS)) { + do { + parse_type (true, false); + } while (accept (TokenType.COMMA)); + Report.warning (method.source_reference, "`throws' is ignored in the Dova profile"); + } + } else { + if (accept (TokenType.THROWS)) { + do { + method.add_error_type (parse_type (true, false)); + } while (accept (TokenType.COMMA)); + } } while (accept (TokenType.REQUIRES)) { expect (TokenType.OPEN_PARENS); @@ -3361,10 +3386,21 @@ public class Vala.Parser : CodeVisitor { } while (accept (TokenType.COMMA)); } expect (TokenType.CLOSE_PARENS); - if (accept (TokenType.THROWS)) { - do { - d.add_error_type (parse_type (true, false)); - } while (accept (TokenType.COMMA)); + if (context.profile == Profile.DOVA) { + var error_type = new UnresolvedType.from_symbol (new UnresolvedSymbol (new UnresolvedSymbol (null, "Dova"), "Error"), d.source_reference); + d.add_error_type (error_type); + if (accept (TokenType.THROWS)) { + do { + parse_type (true, false); + } while (accept (TokenType.COMMA)); + Report.warning (d.source_reference, "`throws' is ignored in the Dova profile"); + } + } else { + if (accept (TokenType.THROWS)) { + do { + d.add_error_type (parse_type (true, false)); + } while (accept (TokenType.COMMA)); + } } expect (TokenType.SEMICOLON); diff --git a/vala/valapropertyaccessor.vala b/vala/valapropertyaccessor.vala index a4227d987..9e3944e39 100644 --- a/vala/valapropertyaccessor.vala +++ b/vala/valapropertyaccessor.vala @@ -1,6 +1,6 @@ /* valapropertyaccessor.vala * - * Copyright (C) 2006-2009 Jürg Billeter + * Copyright (C) 2006-2010 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 @@ -223,9 +223,11 @@ public class Vala.PropertyAccessor : Symbol { body.check (analyzer); - foreach (DataType body_error_type in body.get_error_types ()) { - if (!((ErrorType) body_error_type).dynamic_error) { - Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string())); + if (analyzer.context.profile != Profile.DOVA) { + foreach (DataType body_error_type in body.get_error_types ()) { + if (!((ErrorType) body_error_type).dynamic_error) { + Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string())); + } } } } -- 2.47.2