[vala/wip/transform: 83/179] Collect error_types on demand to allow transformations



commit 4e41bef8dd6ff6db766dc303dba4afab0664487d
Author: Luca Bruno <lucabru src gnome org>
Date:   Sun Aug 7 12:44:41 2011 +0200

    Collect error_types on demand to allow transformations

 codegen/valaccodedelegatemodule.vala   |   10 ++--
 codegen/valaccodemethodmodule.vala     |    8 ++-
 codegen/valagasyncmodule.vala          |    4 +-
 codegen/valagdbusclientmodule.vala     |    6 ++-
 codegen/valagdbusservermodule.vala     |    4 +-
 codegen/valagerrormodule.vala          |   10 ++--
 vala/valaassignment.vala               |    8 ++-
 vala/valabinaryexpression.vala         |    5 ++
 vala/valablock.vala                    |    8 ++-
 vala/valacallabletype.vala             |    3 +-
 vala/valacastexpression.vala           |    6 ++-
 vala/valacodenode.vala                 |   48 ++++------------------
 vala/valacodewriter.vala               |   66 ++++++++++++++++---------------
 vala/valaconditionalexpression.vala    |    6 +++
 vala/valaconstructor.vala              |    4 +-
 vala/valacreationmethod.vala           |   24 ++++++++----
 vala/valadeclarationstatement.vala     |   21 +++++-----
 vala/valadelegate.vala                 |   67 ++++++++++++++++++++++++--------
 vala/valadelegatetype.vala             |    8 +++-
 vala/valaelementaccess.vala            |   13 +++++-
 vala/valaexpressionstatement.vala      |    6 ++-
 vala/valaflowanalyzer.vala             |    6 ++-
 vala/valaforeachstatement.vala         |   11 ++++-
 vala/valagirparser.vala                |   55 ++++++++++++++++----------
 vala/valaifstatement.vala              |   25 ++++++------
 vala/valalambdaexpression.vala         |    4 +-
 vala/valaloop.vala                     |    6 ++-
 vala/valamemberaccess.vala             |    6 +++
 vala/valamethod.vala                   |   63 +++++++++++++++++++++++++-----
 vala/valamethodcall.vala               |   61 ++++++++++------------------
 vala/valaobjectcreationexpression.vala |   24 +++++------
 vala/valaparser.vala                   |   38 +++++++++---------
 vala/valapointerindirection.vala       |    8 +++-
 vala/valapropertyaccessor.vala         |    4 +-
 vala/valareturnstatement.vala          |    8 +++-
 vala/valastatementlist.vala            |    6 +++
 vala/valaswitchsection.vala            |   12 +++--
 vala/valaswitchstatement.vala          |   13 ++++--
 vala/valathrowstatement.vala           |   14 ++++--
 vala/valatrystatement.vala             |   49 ++++++++++++-----------
 vala/valaunaryexpression.vala          |    6 ++-
 valadoc/symbolresolver.vala            |   12 +++--
 vapigen/valagidlparser.vala            |    6 ++-
 43 files changed, 459 insertions(+), 313 deletions(-)
---
diff --git a/codegen/valaccodedelegatemodule.vala b/codegen/valaccodedelegatemodule.vala
index 82202c9..0932a90 100644
--- a/codegen/valaccodedelegatemodule.vala
+++ b/codegen/valaccodedelegatemodule.vala
@@ -60,12 +60,12 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
                        // handle array parameters
                        if (get_ccode_array_length (param) && param.variable_type is ArrayType) {
                                var array_type = (ArrayType) param.variable_type;
-
+                               
                                var length_ctype = "int";
                                if (param.direction != ParameterDirection.IN) {
                                        length_ctype = "int*";
                                }
-
+                               
                                for (int dim = 1; dim <= array_type.rank; dim++) {
                                        cparam = new CCodeParameter (get_parameter_array_length_cname (param, 
dim), length_ctype);
                                        cfundecl.add_parameter (cparam);
@@ -115,7 +115,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
                        var cparam = new CCodeParameter ("user_data", "void*");
                        cfundecl.add_parameter (cparam);
                }
-               if (d.get_error_types ().size > 0) {
+               if (d.tree_can_fail) {
                        var cparam = new CCodeParameter ("error", "GError**");
                        cfundecl.add_parameter (cparam);
                }
@@ -263,7 +263,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
                        cparam_map.set (get_param_pos (-3), cparam);
                }
 
-               if (m.get_error_types ().size > 0) {
+               if (m.tree_can_fail) {
                        var cparam = new CCodeParameter ("error", "GError**");
                        cparam_map.set (get_param_pos (-1), cparam);
                }
@@ -387,7 +387,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
                        carg_map.set (get_param_pos (-3), new CCodeIdentifier ("result"));
                }
 
-               if (m.get_error_types ().size > 0) {
+               if (m.tree_can_fail) {
                        carg_map.set (get_param_pos (-1), new CCodeIdentifier ("error"));
                }
 
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index 8caaef3..1d10b95 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -111,7 +111,9 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
                }
 
                if (m.has_error_type_parameter ()) {
-                       foreach (DataType error_type in m.get_error_types ()) {
+                       var error_types = new ArrayList<DataType> ();
+                       m.get_error_types (error_types);
+                       foreach (DataType error_type in error_types) {
                                generate_type_declaration (error_type, decl_space);
                        }
 
@@ -1103,7 +1105,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
                                vcast = new CCodeIdentifier ("self");
                        }
                }
-
+       
                cname = get_ccode_vfunc_name (m);
                if (suffix == "_finish" && cname.has_suffix ("_async")) {
                        cname = cname.substring (0, cname.length - "_async".length);
@@ -1202,7 +1204,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
                                return;
                        }
                }
-
+               
                ccode.add_expression (ccheck);
        }
 
diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala
index 54df523..330f571 100644
--- a/codegen/valagasyncmodule.vala
+++ b/codegen/valagasyncmodule.vala
@@ -617,7 +617,7 @@ public class Vala.GAsyncModule : GtkModule {
                var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_task_propagate_pointer"));
                ccall.add_argument (async_result_cast);
 
-               if (m.get_error_types ().size > 0) {
+               if (m.tree_can_fail) {
                        ccall.add_argument (new CCodeIdentifier ("error"));
                } else {
                        ccall.add_argument (new CCodeConstant ("NULL"));
@@ -635,7 +635,7 @@ public class Vala.GAsyncModule : GtkModule {
                }
 
                // If a task is cancelled, g_task_propagate_pointer returns NULL
-               if (m.get_error_types ().size > 0 || has_cancellable) {
+               if (m.tree_can_fail || has_cancellable) {
                        var is_null = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new 
CCodeConstant ("NULL"), data_var);
 
                        ccode.open_if (is_null);
diff --git a/codegen/valagdbusclientmodule.vala b/codegen/valagdbusclientmodule.vala
index 4d9caa1..1337c7b 100644
--- a/codegen/valagdbusclientmodule.vala
+++ b/codegen/valagdbusclientmodule.vala
@@ -565,7 +565,7 @@ public class Vala.GDBusClientModule : GDBusModule {
                        cfile.add_include ("gio/gunixfdlist.h");
                }
 
-               bool has_error_argument = (m.get_error_types ().size > 0);
+               bool has_error_argument = m.tree_can_fail;
                CCodeExpression error_argument;
                if (has_error_argument) {
                        error_argument = new CCodeIdentifier ("error");
@@ -592,7 +592,9 @@ public class Vala.GDBusClientModule : GDBusModule {
                        }
 
                        // register errors
-                       foreach (var error_type in m.get_error_types ()) {
+                       var error_types = new ArrayList<DataType> ();
+                       m.get_error_types (error_types);
+                       foreach (var error_type in error_types) {
                                var errtype = (ErrorType) error_type;
                                if (errtype.error_domain != null) {
                                        ccode.add_expression (new CCodeIdentifier (get_ccode_upper_case_name 
(errtype.error_domain)));
diff --git a/codegen/valagdbusservermodule.vala b/codegen/valagdbusservermodule.vala
index 68909c0..a69467d 100644
--- a/codegen/valagdbusservermodule.vala
+++ b/codegen/valagdbusservermodule.vala
@@ -220,7 +220,7 @@ public class Vala.GDBusServerModule : GDBusClientModule {
                }
 
                if (!m.coroutine || ready) {
-                       if (m.get_error_types ().size > 0) {
+                       if (m.tree_can_fail) {
                                ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, 
new CCodeIdentifier ("error")));
                        }
                }
@@ -232,7 +232,7 @@ public class Vala.GDBusServerModule : GDBusClientModule {
                                ccode.add_assignment (new CCodeIdentifier ("result"), ccall);
                        }
 
-                       if (m.get_error_types ().size > 0) {
+                       if (m.tree_can_fail) {
                                ccode.open_if (new CCodeIdentifier ("error"));
 
                                var return_error = new CCodeFunctionCall (new CCodeIdentifier 
("g_dbus_method_invocation_return_gerror"));
diff --git a/codegen/valagerrormodule.vala b/codegen/valagerrormodule.vala
index add71ce..a7a7a54 100644
--- a/codegen/valagerrormodule.vala
+++ b/codegen/valagerrormodule.vala
@@ -191,9 +191,7 @@ public class Vala.GErrorModule : CCodeDelegateModule {
                        }
 
                        var error_types = new ArrayList<DataType> ();
-                       foreach (DataType node_error_type in node.get_error_types ()) {
-                               error_types.add (node_error_type);
-                       }
+                       node.get_error_types (error_types);
 
                        bool has_general_catch_clause = false;
 
@@ -258,11 +256,13 @@ public class Vala.GErrorModule : CCodeDelegateModule {
                                // should never happen with correct bindings
                                uncaught_error_statement (inner_error, true);
                        }
-               } else if (current_method != null && current_method.get_error_types ().size > 0) {
+               } else if (current_method != null && current_method.tree_can_fail) {
                        // current method can fail, propagate error
                        CCodeBinaryExpression ccond = null;
 
-                       foreach (DataType error_type in current_method.get_error_types ()) {
+                       var error_types = new ArrayList<DataType> ();
+                       current_method.get_error_types (error_types);
+                       foreach (DataType error_type in error_types) {
                                // If GLib.Error is allowed we propagate everything
                                if (error_type.equals (gerror_type)) {
                                        ccond = null;
diff --git a/vala/valaassignment.vala b/vala/valaassignment.vala
index d458d19..83c36fe 100644
--- a/vala/valaassignment.vala
+++ b/vala/valaassignment.vala
@@ -101,6 +101,11 @@ public class Vala.Assignment : Expression {
                return left.is_accessible (sym) && right.is_accessible (sym);
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               left.get_error_types (collection, source_reference);
+               right.get_error_types (collection, source_reference);
+       }
+
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
@@ -443,9 +448,6 @@ public class Vala.Assignment : Expression {
                        value_type = null;
                }
 
-               add_error_types (left.get_error_types ());
-               add_error_types (right.get_error_types ());
-
                return !error;
        }
 
diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala
index 99a54aa..96bf833 100644
--- a/vala/valabinaryexpression.vala
+++ b/vala/valabinaryexpression.vala
@@ -154,6 +154,11 @@ public class Vala.BinaryExpression : Expression {
                return left.is_accessible (sym) && right.is_accessible (sym);
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               left.get_error_types (collection, source_reference);
+               right.get_error_types (collection, source_reference);
+       }
+
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
diff --git a/vala/valablock.vala b/vala/valablock.vala
index 6388a57..d4dd4ff 100644
--- a/vala/valablock.vala
+++ b/vala/valablock.vala
@@ -158,12 +158,14 @@ public class Vala.Block : Symbol, Statement {
                        constant.active = false;
                }
 
+               return !error;
+       }
+
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
                // use get_statements () instead of statement_list to not miss errors within StatementList 
objects
                foreach (Statement stmt in get_statements ()) {
-                       add_error_types (stmt.get_error_types ());
+                       stmt.get_error_types (collection, source_reference);
                }
-
-               return !error;
        }
 
        public override void emit (CodeGenerator codegen) {
diff --git a/vala/valacallabletype.vala b/vala/valacallabletype.vala
index 0642fa6..c604de8 100644
--- a/vala/valacallabletype.vala
+++ b/vala/valacallabletype.vala
@@ -90,7 +90,8 @@ public abstract class Vala.CallableType : DataType {
                builder.append_c (')');
 
                // Append error-types
-               var error_types = get_error_types ();
+               var error_types = new ArrayList<DataType> ();
+               get_error_types (error_types);
                if (error_types.size > 0) {
                        builder.append (" throws ");
 
diff --git a/vala/valacastexpression.vala b/vala/valacastexpression.vala
index 8d35e1e..ba3ee5b 100644
--- a/vala/valacastexpression.vala
+++ b/vala/valacastexpression.vala
@@ -37,7 +37,7 @@ public class Vala.CastExpression : Expression {
                        _inner.parent_node = this;
                }
        }
-
+       
        /**
         * The target type.
         */
@@ -122,6 +122,10 @@ public class Vala.CastExpression : Expression {
                }
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               inner.get_error_types (collection, source_reference);
+       }
+
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
diff --git a/vala/valacodenode.vala b/vala/valacodenode.vala
index 70bc77f..a4a85e5 100644
--- a/vala/valacodenode.vala
+++ b/vala/valacodenode.vala
@@ -61,53 +61,20 @@ public abstract class Vala.CodeNode {
        /**
         * Specifies that this node or a child node may throw an exception.
         */
-       public bool tree_can_fail {
-               get { return _error_types != null && _error_types.size > 0; }
+       public bool tree_can_fail { 
+               get {
+                       var error_types = new ArrayList<DataType> ();
+                       get_error_types (error_types);
+                       return error_types.size > 0;
+               }
        }
 
-       private List<DataType> _error_types;
-       private static List<DataType> _empty_type_list;
        private AttributeCache[] attributes_cache;
 
        static int last_temp_nr = 0;
        static int next_attribute_cache_index = 0;
 
        /**
-        * Specifies the exceptions that can be thrown by this node or a child node
-        */
-       public List<DataType> get_error_types () {
-               if (_error_types != null) {
-                       return _error_types;
-               }
-               if (_empty_type_list == null) {
-                       _empty_type_list = new ArrayList<DataType> ();
-               }
-               return _empty_type_list;
-       }
-
-       /**
-        * Adds an error type to the exceptions that can be thrown by this node
-        * or a child node
-        */
-       public void add_error_type (DataType error_type) {
-               if (_error_types == null) {
-                       _error_types = new ArrayList<DataType> ();
-               }
-               _error_types.add (error_type);
-               error_type.parent_node = this;
-       }
-
-       /**
-        * Adds a collection of error types to the exceptions that can be thrown by this node
-        * or a child node
-        */
-       public void add_error_types (List<DataType> error_types) {
-               foreach (DataType error_type in error_types) {
-                       add_error_type (error_type);
-               }
-       }
-
-       /**
         * Visits this code node with the specified CodeVisitor.
         *
         * @param visitor the visitor to be called while traversing
@@ -383,6 +350,9 @@ public abstract class Vala.CodeNode {
        public virtual void get_used_variables (Collection<Variable> collection) {
        }
 
+       public virtual void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+       }
+
        public static string get_temp_name () {
                return "." + (++last_temp_nr).to_string ();
        }
diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala
index b442bb2..afe17d5 100644
--- a/vala/valacodewriter.vala
+++ b/vala/valacodewriter.vala
@@ -31,9 +31,9 @@ public class Vala.CodeWriter : CodeVisitor {
        static GLib.Regex fix_indent_regex;
 
        private CodeContext context;
-
+       
        FileStream stream;
-
+       
        int indent;
        /* at begin of line */
        bool bol = true;
@@ -240,7 +240,7 @@ public class Vala.CodeWriter : CodeVisitor {
                }
 
                write_attributes (cl);
-
+               
                write_indent ();
                write_accessibility (cl);
                if (cl.is_abstract) {
@@ -254,7 +254,7 @@ public class Vala.CodeWriter : CodeVisitor {
                var base_types = cl.get_base_types ();
                if (base_types.size > 0) {
                        write_string (" : ");
-
+               
                        bool first = true;
                        foreach (DataType base_type in base_types) {
                                if (!first) {
@@ -392,7 +392,7 @@ public class Vala.CodeWriter : CodeVisitor {
                var prerequisites = iface.get_prerequisites ();
                if (prerequisites.size > 0) {
                        write_string (" : ");
-
+               
                        bool first = true;
                        foreach (DataType prerequisite in prerequisites) {
                                if (!first) {
@@ -565,7 +565,7 @@ public class Vala.CodeWriter : CodeVisitor {
                write_string ("const ");
 
                write_type (c.type_reference);
-
+                       
                write_string (" ");
                write_identifier (c.name);
                write_type_suffix (c.type_reference);
@@ -606,14 +606,14 @@ public class Vala.CodeWriter : CodeVisitor {
                }
 
                write_type (f.variable_type);
-
+                       
                write_string (" ");
                write_identifier (f.name);
                write_type_suffix (f.variable_type);
                write_string (";");
                write_newline ();
        }
-
+       
        private void write_error_domains (List<DataType> error_domains) {
                if (error_domains.size > 0) {
                        write_string (" throws ");
@@ -639,12 +639,12 @@ public class Vala.CodeWriter : CodeVisitor {
                        if (i > 1) {
                                write_string (", ");
                        }
-
+                       
                        if (param.ellipsis) {
                                write_string ("...");
                                continue;
                        }
-
+                       
                        write_attributes (param);
 
                        if (param.params_array) {
@@ -671,7 +671,7 @@ public class Vala.CodeWriter : CodeVisitor {
                        write_string (" ");
                        write_identifier (param.name);
                        write_type_suffix (param.variable_type);
-
+                       
                        if (param.initializer != null) {
                                write_string (" = ");
                                param.initializer.accept (this);
@@ -702,19 +702,21 @@ public class Vala.CodeWriter : CodeVisitor {
 
                write_accessibility (cb);
                write_string ("delegate ");
-
+               
                write_return_type (cb.return_type);
-
+               
                write_string (" ");
                write_identifier (cb.name);
 
                write_type_parameters (cb.get_type_parameters ());
 
                write_string (" ");
-
+               
                write_params (cb.get_parameters ());
 
-               write_error_domains (cb.get_error_types ());
+               var error_types = new ArrayList<DataType> ();
+               cb.get_error_types (error_types);
+               write_error_domains (error_types);
 
                write_string (";");
 
@@ -756,7 +758,7 @@ public class Vala.CodeWriter : CodeVisitor {
 
                write_indent ();
                write_accessibility (m);
-
+               
                if (m is CreationMethod) {
                        if (m.coroutine) {
                                write_string ("async ");
@@ -789,7 +791,7 @@ public class Vala.CodeWriter : CodeVisitor {
                        if (m.coroutine) {
                                write_string ("async ");
                        }
-
+               
                        write_return_type (m.return_type);
                        write_string (" ");
 
@@ -799,10 +801,12 @@ public class Vala.CodeWriter : CodeVisitor {
 
                        write_string (" ");
                }
-
+               
                write_params (m.get_parameters ());
 
-               write_error_domains (m.get_error_types ());
+               var error_types = new ArrayList<DataType> ();
+               m.get_error_types (error_types);
+               write_error_domains (error_types);
 
                write_code_block (m.body);
 
@@ -879,13 +883,13 @@ public class Vala.CodeWriter : CodeVisitor {
                if (!check_accessibility (sig)) {
                        return;
                }
-
+               
                if (context.vapi_comments && sig.comment != null) {
                        write_comment (sig.comment);
                }
 
                write_attributes (sig);
-
+               
                write_indent ();
                write_accessibility (sig);
 
@@ -894,14 +898,14 @@ public class Vala.CodeWriter : CodeVisitor {
                }
 
                write_string ("signal ");
-
+               
                write_return_type (sig.return_type);
-
+               
                write_string (" ");
                write_identifier (sig.name);
-
+               
                write_string (" ");
-
+               
                write_params (sig.get_parameters ());
 
                write_string (";");
@@ -1235,7 +1239,7 @@ public class Vala.CodeWriter : CodeVisitor {
 
                write_string (")");
        }
-
+       
        public override void visit_element_access (ElementAccess expr) {
                expr.container.accept (this);
                write_string ("[");
@@ -1530,13 +1534,13 @@ public class Vala.CodeWriter : CodeVisitor {
                write_string (fixed_content);
                write_string ("*/");
        }
-
+       
        private void write_identifier (string s) {
                char* id = (char*)s;
                int id_length = (int)s.length;
                if (Vala.Scanner.get_identifier_or_keyword (id, id_length) != Vala.TokenType.IDENTIFIER ||
                    s.get_char ().isdigit ()) {
-                       stream.putc ('@');
+                       stream.putc ('@'); 
                }
                write_string (s);
        }
@@ -1566,12 +1570,12 @@ public class Vala.CodeWriter : CodeVisitor {
                stream.puts (s);
                bol = false;
        }
-
+       
        private void write_newline () {
                stream.putc ('\n');
                bol = true;
        }
-
+       
        void write_code_block (Block? block) {
                if (block == null || type != CodeWriterType.DUMP) {
                        write_string (";");
@@ -1591,7 +1595,7 @@ public class Vala.CodeWriter : CodeVisitor {
                write_newline ();
                indent++;
        }
-
+       
        private void write_end_block () {
                indent--;
                write_indent ();
diff --git a/vala/valaconditionalexpression.vala b/vala/valaconditionalexpression.vala
index 4a3d139..dc953f1 100644
--- a/vala/valaconditionalexpression.vala
+++ b/vala/valaconditionalexpression.vala
@@ -104,6 +104,12 @@ public class Vala.ConditionalExpression : Expression {
                return condition.is_accessible (sym) && true_expression.is_accessible (sym) && 
false_expression.is_accessible (sym);
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               condition.get_error_types (collection, source_reference);
+               true_expression.get_error_types (collection, source_reference);
+               false_expression.get_error_types (collection, source_reference);
+       }
+
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
diff --git a/vala/valaconstructor.vala b/vala/valaconstructor.vala
index 3d19596..86f24de 100644
--- a/vala/valaconstructor.vala
+++ b/vala/valaconstructor.vala
@@ -74,7 +74,9 @@ public class Vala.Constructor : Subroutine {
                        body.check (context);
                }
 
-               foreach (DataType body_error_type in body.get_error_types ()) {
+               var body_errors = new ArrayList<DataType> ();
+               body.get_error_types (body_errors);
+               foreach (DataType body_error_type in body_errors) {
                        if (!((ErrorType) body_error_type).dynamic_error) {
                                Report.warning (body_error_type.source_reference, "unhandled error 
`%s'".printf (body_error_type.to_string()));
                        }
diff --git a/vala/valacreationmethod.vala b/vala/valacreationmethod.vala
index 7389b52..aa433ac 100644
--- a/vala/valacreationmethod.vala
+++ b/vala/valacreationmethod.vala
@@ -60,8 +60,10 @@ public class Vala.CreationMethod : Method {
                        param.accept (visitor);
                }
 
-               foreach (DataType error_type in get_error_types ()) {
-                       error_type.accept (visitor);
+               if (error_types != null) {
+                       foreach (DataType error_type in error_types) {
+                               error_type.accept (visitor);
+                       }
                }
 
                foreach (Expression precondition in get_preconditions ()) {
@@ -101,8 +103,10 @@ public class Vala.CreationMethod : Method {
                        i++;
                }
 
-               foreach (DataType error_type in get_error_types ()) {
-                       error_type.check (context);
+               if (error_types != null) {
+                       foreach (DataType error_type in error_types) {
+                               error_type.check (context);
+                       }
                }
 
                foreach (Expression precondition in get_preconditions ()) {
@@ -146,11 +150,15 @@ public class Vala.CreationMethod : Method {
 
                // check that all errors that can be thrown in the method body are declared
                if (body != null) {
-                       foreach (DataType body_error_type in body.get_error_types ()) {
+                       var body_errors = new ArrayList<DataType> ();
+                       body.get_error_types (body_errors);
+                       foreach (DataType body_error_type in body_errors) {
                                bool can_propagate_error = false;
-                               foreach (DataType method_error_type in get_error_types ()) {
-                                       if (body_error_type.compatible (method_error_type)) {
-                                               can_propagate_error = true;
+                               if (error_types != null) {
+                                       foreach (DataType method_error_type in error_types) {
+                                               if (body_error_type.compatible (method_error_type)) {
+                                                       can_propagate_error = true;
+                                               }
                                        }
                                }
                                if (!can_propagate_error && !((ErrorType) body_error_type).dynamic_error) {
diff --git a/vala/valadeclarationstatement.vala b/vala/valadeclarationstatement.vala
index f0a3d41..ab652e9 100644
--- a/vala/valadeclarationstatement.vala
+++ b/vala/valadeclarationstatement.vala
@@ -62,6 +62,16 @@ public class Vala.DeclarationStatement : CodeNode, Statement {
                declaration.accept (visitor);
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               if (source_reference == null) {
+                       source_reference = this.source_reference;
+               }
+               var local = declaration as LocalVariable;
+               if (local != null && local.initializer != null) {
+                       local.initializer.get_error_types (collection, source_reference);
+               }
+       }
+
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
@@ -71,17 +81,6 @@ public class Vala.DeclarationStatement : CodeNode, Statement {
 
                declaration.check (context);
 
-               var local = declaration as LocalVariable;
-               if (local != null && local.initializer != null) {
-                       foreach (DataType error_type in local.initializer.get_error_types ()) {
-                               // ensure we can trace back which expression may throw errors of this type
-                               var initializer_error_type = error_type.copy ();
-                               initializer_error_type.source_reference = local.initializer.source_reference;
-
-                               add_error_type (initializer_error_type);
-                       }
-               }
-
                return !error;
        }
 
diff --git a/vala/valadelegate.vala b/vala/valadelegate.vala
index b880634..aa95389 100644
--- a/vala/valadelegate.vala
+++ b/vala/valadelegate.vala
@@ -68,6 +68,8 @@ public class Vala.Delegate : TypeSymbol, Callable {
        private DataType _return_type;
        private bool? _has_target;
 
+       private List<DataType> error_types;
+
        /**
         * Creates a new delegate.
         *
@@ -185,21 +187,23 @@ public class Vala.Delegate : TypeSymbol, Callable {
                        return false;
                }
 
-               var error_types = get_error_types ();
-               var method_error_types = m.get_error_types ();
+               var method_error_types = new ArrayList<DataType> ();
+               m.get_error_types (method_error_types);
 
                // method must throw error if the delegate does
-               if (error_types.size > 0 && method_error_types.size == 0) {
+               if (error_types != null && error_types.size > 0 && method_error_types.size == 0) {
                        return false;
                }
 
                // method may throw less but not more errors than the delegate
                foreach (DataType method_error_type in method_error_types) {
                        bool match = false;
-                       foreach (DataType delegate_error_type in error_types) {
-                               if (method_error_type.compatible (delegate_error_type)) {
-                                       match = true;
-                                       break;
+                       if (error_types != null) {
+                               foreach (DataType delegate_error_type in error_types) {
+                                       if (method_error_type.compatible (delegate_error_type)) {
+                                               match = true;
+                                               break;
+                                       }
                                }
                        }
 
@@ -226,8 +230,10 @@ public class Vala.Delegate : TypeSymbol, Callable {
                        param.accept (visitor);
                }
 
-               foreach (DataType error_type in get_error_types ()) {
-                       error_type.accept (visitor);
+               if (error_types != null) {
+                       foreach (DataType error_type in error_types) {
+                               error_type.accept (visitor);
+                       }
                }
        }
 
@@ -235,16 +241,43 @@ public class Vala.Delegate : TypeSymbol, Callable {
                return false;
        }
 
+       /**
+        * Adds an error type to the exceptions that can be
+        * thrown by this delegate.
+        */
+       public void add_error_type (DataType error_type) {
+               if (error_types == null) {
+                       error_types = new ArrayList<DataType> ();
+               }
+               error_types.add (error_type);
+               error_type.parent_node = this;
+       }
+
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               if (error_types != null) {
+                       foreach (var error_type in error_types) {
+                               if (source_reference != null) {
+                                       var type = error_type.copy ();
+                                       type.source_reference = source_reference;
+                                       collection.add (type);
+                               } else {
+                                       collection.add (error_type);
+                               }
+                       }
+               }
+       }
+
        public override void replace_type (DataType old_type, DataType new_type) {
                if (return_type == old_type) {
                        return_type = new_type;
                        return;
                }
-               var error_types = get_error_types ();
-               for (int i = 0; i < error_types.size; i++) {
-                       if (error_types[i] == old_type) {
-                               error_types[i] = new_type;
-                               return;
+               if (error_types != null) {
+                       for (int i = 0; i < error_types.size; i++) {
+                               if (error_types[i] == old_type) {
+                                       error_types[i] = new_type;
+                                       return;
+                               }
                        }
                }
        }
@@ -266,8 +299,10 @@ public class Vala.Delegate : TypeSymbol, Callable {
                        param.check (context);
                }
 
-               foreach (DataType error_type in get_error_types ()) {
-                       error_type.check (context);
+               if (error_types != null) {
+                       foreach (DataType error_type in error_types) {
+                               error_type.check (context);
+                       }
                }
 
                return !error;
diff --git a/vala/valadelegatetype.vala b/vala/valadelegatetype.vala
index 8e62d75..3394043 100644
--- a/vala/valadelegatetype.vala
+++ b/vala/valadelegatetype.vala
@@ -189,9 +189,13 @@ public class Vala.DelegateType : CallableType {
                }
 
                // target-delegate may throw less but not more errors than the delegate
-               foreach (DataType error_type in get_error_types ()) {
+               var error_types = new ArrayList<DataType> ();
+               get_error_types (error_types);
+               foreach (DataType error_type in error_types) {
                        bool match = false;
-                       foreach (DataType delegate_error_type in dt_target.get_error_types ()) {
+                       var delegate_error_types = new ArrayList<DataType> ();
+                       dt_target.get_error_types (delegate_error_types);
+                       foreach (DataType delegate_error_type in delegate_error_types) {
                                if (error_type.compatible (delegate_error_type)) {
                                        match = true;
                                        break;
diff --git a/vala/valaelementaccess.vala b/vala/valaelementaccess.vala
index 993f9c1..0bd5ca3 100644
--- a/vala/valaelementaccess.vala
+++ b/vala/valaelementaccess.vala
@@ -56,12 +56,12 @@ public class Vala.ElementAccess : Expression {
        public List<Expression> get_indices () {
                return indices;
        }
-
+       
        public ElementAccess (Expression container, SourceReference source_reference) {
                this.source_reference = source_reference;
                this.container = container;
        }
-
+       
        public override void accept (CodeVisitor visitor) {
                visitor.visit_element_access (this);
 
@@ -79,7 +79,7 @@ public class Vala.ElementAccess : Expression {
                if (container == old_node) {
                        container = new_node;
                }
-
+               
                int index = indices.index_of (old_node);
                if (index >= 0 && new_node.parent_node == null) {
                        indices[index] = new_node;
@@ -106,6 +106,13 @@ public class Vala.ElementAccess : Expression {
                return container.is_accessible (sym);
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               container.get_error_types (collection, source_reference);
+               foreach (Expression e in indices) {
+                       e.get_error_types (collection, source_reference);
+               }
+       }
+
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
diff --git a/vala/valaexpressionstatement.vala b/vala/valaexpressionstatement.vala
index 912e5d9..43cebbe 100644
--- a/vala/valaexpressionstatement.vala
+++ b/vala/valaexpressionstatement.vala
@@ -80,11 +80,13 @@ public class Vala.ExpressionStatement : CodeNode, Statement {
                        return false;
                }
 
-               add_error_types (expression.get_error_types ());
-
                return !error;
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               expression.get_error_types (collection, source_reference);
+       }
+
        public override void emit (CodeGenerator codegen) {
                expression.emit (codegen);
 
diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala
index 1fd580a..182c5f5 100644
--- a/vala/valaflowanalyzer.vala
+++ b/vala/valaflowanalyzer.vala
@@ -443,7 +443,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                foreach (CodeNode node in block.get_nodes ()) {
                        var used_variables = new ArrayList<Variable> ();
                        node.get_used_variables (used_variables);
-
+                       
                        foreach (Variable var_symbol in used_variables) {
                                var variable_stack = var_map.get (var_symbol);
                                if (variable_stack == null || variable_stack.size == 0) {
@@ -848,7 +848,9 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                        var last_block = current_block;
 
                        // exceptional control flow
-                       foreach (DataType error_data_type in node.get_error_types()) {
+                       var error_types = new ArrayList<DataType> ();
+                       node.get_error_types (error_types);
+                       foreach (DataType error_data_type in error_types) {
                                var error_type = error_data_type as ErrorType;
                                current_block = last_block;
                                unreachable_reported = true;
diff --git a/vala/valaforeachstatement.vala b/vala/valaforeachstatement.vala
index 2241066..ce831b9 100644
--- a/vala/valaforeachstatement.vala
+++ b/vala/valaforeachstatement.vala
@@ -374,12 +374,17 @@ public class Vala.ForeachStatement : Block {
                add_local_variable (collection_variable);
                collection_variable.active = true;
 
-               add_error_types (collection.get_error_types ());
-               add_error_types (body.get_error_types ());
-
                return !error;
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               if (source_reference == null) {
+                       source_reference = this.source_reference;
+               }
+               this.collection.get_error_types (collection, source_reference);
+               body.get_error_types (collection, source_reference);
+       }
+
        public override void emit (CodeGenerator codegen) {
                if (use_iterator) {
                        base.emit (codegen);
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index 24d1ea5..ddd093b 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -541,7 +541,7 @@ public class Vala.GirParser : CodeVisitor {
                public Node (string? name) {
                        this.name = name;
                }
-
+                       
                public void add_member (Node node) {
                        var nodes = scope[node.name];
                        if (nodes == null) {
@@ -852,7 +852,7 @@ public class Vala.GirParser : CodeVisitor {
                                        }
                                }
                        }
-
+                       
                        if (symbol is Class && girdata != null) {
                                var class_struct = girdata["glib:type-struct"];
                                if (class_struct != null) {
@@ -1005,7 +1005,7 @@ public class Vala.GirParser : CodeVisitor {
                                                // ensure getter vfunc if the property is abstract
                                                if (m != null) {
                                                        getter.process (parser);
-                                                       if (m.return_type is VoidType || 
m.get_parameters().size != 0 || m.get_error_types ().size > 0) {
+                                                       if (m.return_type is VoidType || 
m.get_parameters().size != 0 || m.tree_can_fail) {
                                                                prop.set_attribute ("NoAccessorMethod", true);
                                                        } else {
                                                                if (getter.name == name) {
@@ -1015,7 +1015,7 @@ public class Vala.GirParser : CodeVisitor {
                                                                                }
                                                                        }
                                                                }
-
+                                                               
                                                                prop.get_accessor.value_type.value_owned = 
m.return_type.value_owned;
 
                                                                if (!m.is_abstract && !m.is_virtual && 
prop.is_abstract) {
@@ -1032,7 +1032,7 @@ public class Vala.GirParser : CodeVisitor {
                                                // ensure setter vfunc if the property is abstract
                                                if (m != null) {
                                                        setter.process (parser);
-                                                       if (!(m.return_type is VoidType || m.return_type is 
BooleanType) || m.get_parameters ().size != 1 || m.get_error_types ().size > 0) {
+                                                       if (!(m.return_type is VoidType || m.return_type is 
BooleanType) || m.get_parameters ().size != 1 || m.tree_can_fail) {
                                                                prop.set_attribute ("NoAccessorMethod", true);
                                                                prop.set_attribute ("ConcreteAccessor", 
false);
                                                        } else {
@@ -1055,7 +1055,7 @@ public class Vala.GirParser : CodeVisitor {
                                                        var base_prop_node = parser.base_interface_property 
(this);
                                                        if (base_prop_node != null) {
                                                                base_prop_node.process (parser);
-
+                                                               
                                                                var base_property = (Property) 
base_prop_node.symbol;
                                                                if (base_property.get_attribute 
("ConcreteAccessor") != null) {
                                                                        prop.set_attribute 
("NoAccessorMethod", false);
@@ -1065,7 +1065,7 @@ public class Vala.GirParser : CodeVisitor {
                                                                        if (prop.set_accessor != null) {
                                                                                
prop.set_accessor.value_type.value_owned = base_property.set_accessor.value_type.value_owned;
                                                                        }
-
+                                                                       
                                                                }
                                                        }
                                                }
@@ -1856,7 +1856,7 @@ public class Vala.GirParser : CodeVisitor {
                }
                return type_id;
        }
-
+       
        void set_array_ccode (Symbol sym, ParameterInfo info) {
                sym.set_attribute_double ("CCode", "array_length_pos", info.vala_idx);
                if (sym is Parameter) {
@@ -3168,12 +3168,21 @@ public class Vala.GirParser : CodeVisitor {
 
                if (!(metadata.get_expression (ArgumentType.THROWS) is NullLiteral)) {
                        if (metadata.has_argument (ArgumentType.THROWS)) {
-                               var error_types = metadata.get_string(ArgumentType.THROWS).split(",");
-                               foreach (var error_type in error_types) {
-                                       s.add_error_type (parse_type_from_string (error_type, true, 
metadata.get_source_reference (ArgumentType.THROWS)));
+                               var error_types = metadata.get_string (ArgumentType.THROWS).split(",");
+                               foreach (var error_type_name in error_types) {
+                                       var error_type = parse_type_from_string (error_type_name, true, 
metadata.get_source_reference (ArgumentType.THROWS));
+                                       if (s is Method) {
+                                               ((Method) s).add_error_type (error_type);
+                                       } else {
+                                               ((Delegate) s).add_error_type (error_type);
+                                       }
                                }
                        } else if (throws_string == "1") {
-                               s.add_error_type (new ErrorType (null, null));
+                               if (s is Method) {
+                                       ((Method) s).add_error_type (new ErrorType (null, null));
+                               } else {
+                                       ((Delegate) s).add_error_type (new ErrorType (null, null));
+                               }
                        }
                }
 
@@ -3673,24 +3682,26 @@ public class Vala.GirParser : CodeVisitor {
                                base_node.process (this);
                                orig = (Delegate) base_node.symbol;
                        }
-
+                       
                        var deleg = new Delegate (alias.name, orig.return_type.copy (), 
alias.source_reference);
                        deleg.access = orig.access;
-
+                       
                        foreach (var param in orig.get_parameters ()) {
                                deleg.add_parameter (param.copy ());
                        }
 
-                       foreach (var error_type in orig.get_error_types ()) {
+                       var error_types = new ArrayList<DataType> ();
+                       orig.get_error_types (error_types, alias.source_reference);
+                       foreach (var error_type in error_types) {
                                deleg.add_error_type (error_type.copy ());
                        }
-
+                       
                        foreach (var attribute in orig.attributes) {
                                deleg.attributes.append (attribute);
                        }
-
+                       
                        deleg.external = true;
-
+                       
                        alias.symbol = deleg;
                }
 
@@ -3709,7 +3720,7 @@ public class Vala.GirParser : CodeVisitor {
                        // processed in parse_alias
                        return;
                }
-
+               
                var s = node.symbol;
                List<ParameterInfo> parameters = node.parameters;
 
@@ -4085,8 +4096,10 @@ public class Vala.GirParser : CodeVisitor {
                                }
                        }
 
-                       foreach (DataType error_type in finish_method.get_error_types ()) {
-                               method.add_error_type (error_type.copy ());
+                       var error_types = new ArrayList<DataType> ();
+                       finish_method.get_error_types (error_types, method.source_reference);
+                       foreach (DataType error_type in error_types) {
+                               method.add_error_type (error_type);
                        }
                        finish_method_node.processed = true;
                        finish_method_node.merged = true;
diff --git a/vala/valaifstatement.vala b/vala/valaifstatement.vala
index 0f9476d..f2d22e7 100644
--- a/vala/valaifstatement.vala
+++ b/vala/valaifstatement.vala
@@ -38,7 +38,7 @@ public class Vala.IfStatement : CodeNode, Statement {
                        _condition.parent_node = this;
                }
        }
-
+       
        /**
         * The statement to be evaluated if the condition holds.
         */
@@ -49,7 +49,7 @@ public class Vala.IfStatement : CodeNode, Statement {
                        _true_statement.parent_node = this;
                }
        }
-
+       
        /**
         * The optional statement to be evaluated if the condition doesn't hold.
         */
@@ -80,16 +80,16 @@ public class Vala.IfStatement : CodeNode, Statement {
                false_statement = false_stmt;
                source_reference = source;
        }
-
+       
        public override void accept (CodeVisitor visitor) {
                visitor.visit_if_statement (this);
        }
 
        public override void accept_children (CodeVisitor visitor) {
                condition.accept (visitor);
-
+               
                visitor.visit_end_full_expression (condition);
-
+               
                true_statement.accept (visitor);
                if (false_statement != null) {
                        false_statement.accept (visitor);
@@ -102,6 +102,14 @@ public class Vala.IfStatement : CodeNode, Statement {
                }
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               condition.get_error_types (collection, source_reference);
+               true_statement.get_error_types (collection, source_reference);
+               if (false_statement != null) {
+                       false_statement.get_error_types (collection, source_reference);
+               }
+       }
+
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
@@ -130,13 +138,6 @@ public class Vala.IfStatement : CodeNode, Statement {
                        return false;
                }
 
-               add_error_types (condition.get_error_types ());
-               add_error_types (true_statement.get_error_types ());
-
-               if (false_statement != null) {
-                       add_error_types (false_statement.get_error_types ());
-               }
-
                return !error;
        }
 
diff --git a/vala/valalambdaexpression.vala b/vala/valalambdaexpression.vala
index bd722fc..dc17d3d 100644
--- a/vala/valalambdaexpression.vala
+++ b/vala/valalambdaexpression.vala
@@ -197,7 +197,9 @@ public class Vala.LambdaExpression : Expression {
                        return false;
                }
 
-               foreach (var error_type in cb.get_error_types ()) {
+               var error_types = new ArrayList<DataType> ();
+               cb.get_error_types (error_types);
+               foreach (var error_type in error_types) {
                        method.add_error_type (error_type.copy ());
                }
 
diff --git a/vala/valaloop.vala b/vala/valaloop.vala
index 4e6edbe..ce68946 100644
--- a/vala/valaloop.vala
+++ b/vala/valaloop.vala
@@ -61,6 +61,10 @@ public class Vala.Loop : CodeNode, Statement {
                body.accept (visitor);
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               body.get_error_types (collection, source_reference);
+       }
+
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
@@ -70,8 +74,6 @@ public class Vala.Loop : CodeNode, Statement {
 
                body.check (context);
 
-               add_error_types (body.get_error_types ());
-
                return !error;
        }
 
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index a8296d3..4db1279 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -193,6 +193,12 @@ public class Vala.MemberAccess : Expression {
                }
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               if (inner != null) {
+                       inner.get_error_types (collection, source_reference);
+               }
+       }
+
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
diff --git a/vala/valamethod.vala b/vala/valamethod.vala
index 638fe3c..9492770 100644
--- a/vala/valamethod.vala
+++ b/vala/valamethod.vala
@@ -188,6 +188,8 @@ public class Vala.Method : Subroutine, Callable {
        private List<Expression> postconditions;
        private DataType _return_type;
 
+       protected List<DataType> error_types;
+
        private weak Method _base_method;
        private weak Method _base_interface_method;
        private DataType _base_interface_type;
@@ -272,9 +274,11 @@ public class Vala.Method : Subroutine, Callable {
                        param.accept (visitor);
                }
 
-               foreach (DataType error_type in get_error_types ()) {
+               if (error_types != null) {
+                       foreach (DataType error_type in error_types) {
                        error_type.accept (visitor);
                }
+               }
 
                if (result_var != null) {
                        result_var.accept (visitor);
@@ -387,9 +391,12 @@ public class Vala.Method : Subroutine, Callable {
                }
 
                /* this method may throw less but not more errors than the base method */
-               foreach (DataType method_error_type in get_error_types ()) {
+               var base_method_errors = new ArrayList<DataType> ();
+               base_method.get_error_types (base_method_errors);
+               if (error_types != null) {
+                       foreach (DataType method_error_type in error_types) {
                        bool match = false;
-                       foreach (DataType base_method_error_type in base_method.get_error_types ()) {
+                               foreach (DataType base_method_error_type in base_method_errors) {
                                if (method_error_type.compatible (base_method_error_type)) {
                                        match = true;
                                        break;
@@ -401,6 +408,7 @@ public class Vala.Method : Subroutine, Callable {
                                return false;
                        }
                }
+               }
                if (base_method.coroutine != this.coroutine) {
                        invalid_match = "async mismatch";
                        return false;
@@ -509,6 +517,32 @@ public class Vala.Method : Subroutine, Callable {
                return _empty_expression_list;
        }
 
+       /**
+        * Adds an error type to the exceptions that can be
+        * thrown by this method.
+        */
+       public void add_error_type (DataType error_type) {
+               if (error_types == null) {
+                       error_types = new ArrayList<DataType> ();
+               }
+               error_types.add (error_type);
+               error_type.parent_node = this;
+       }
+
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               if (error_types != null) {
+                       foreach (var error_type in error_types) {
+                               if (source_reference != null) {
+                                       var type = error_type.copy ();
+                                       type.source_reference = source_reference;
+                                       collection.add (type);
+                               } else {
+                                       collection.add (error_type);
+                               }
+                       }
+               }
+       }
+
        public override void replace_type (DataType old_type, DataType new_type) {
                if (base_interface_type == old_type) {
                        base_interface_type = new_type;
@@ -518,7 +552,7 @@ public class Vala.Method : Subroutine, Callable {
                        return_type = new_type;
                        return;
                }
-               var error_types = get_error_types ();
+               if (error_types != null) {
                for (int i = 0; i < error_types.size; i++) {
                        if (error_types[i] == old_type) {
                                error_types[i] = new_type;
@@ -526,6 +560,7 @@ public class Vala.Method : Subroutine, Callable {
                        }
                }
        }
+       }
 
        private void find_base_methods () {
                if (base_methods_valid) {
@@ -635,7 +670,7 @@ public class Vala.Method : Subroutine, Callable {
                        this_parameter.variable_type.value_owned = true;
                }
                if (get_attribute ("NoThrow") != null) {
-                       get_error_types ().clear ();
+                       error_types = null;
                }
 
                if (parent_symbol is Class && (is_abstract || is_virtual)) {
@@ -731,7 +766,8 @@ public class Vala.Method : Subroutine, Callable {
                        }
                }
 
-               foreach (DataType error_type in get_error_types ()) {
+               if (error_types != null) {
+                       foreach (DataType error_type in error_types) {
                        error_type.check (context);
 
                        // check whether error type is at least as accessible as the method
@@ -741,6 +777,7 @@ public class Vala.Method : Subroutine, Callable {
                                return false;
                        }
                }
+               }
 
                if (result_var != null) {
                        result_var.check (context);
@@ -831,13 +868,17 @@ public class Vala.Method : Subroutine, Callable {
 
                // check that all errors that can be thrown in the method body are declared
                if (body != null) {
-                       foreach (DataType body_error_type in body.get_error_types ()) {
+                       var body_errors = new ArrayList<DataType> ();
+                       body.get_error_types (body_errors);
+                       foreach (DataType body_error_type in body_errors) {
                                bool can_propagate_error = false;
-                               foreach (DataType method_error_type in get_error_types ()) {
+                               if (error_types != null) {
+                                       foreach (DataType method_error_type in error_types) {
                                        if (body_error_type.compatible (method_error_type)) {
                                                can_propagate_error = true;
                                        }
                                }
+                               }
                                bool is_dynamic_error = body_error_type is ErrorType && ((ErrorType) 
body_error_type).dynamic_error;
                                if (!can_propagate_error && !is_dynamic_error) {
                                        Report.warning (body_error_type.source_reference, "unhandled error 
`%s'".printf (body_error_type.to_string()));
@@ -854,7 +895,9 @@ public class Vala.Method : Subroutine, Callable {
                                bool throws_gerror = false;
                                bool throws_gioerror = false;
                                bool throws_gdbuserror = false;
-                               foreach (DataType error_type in get_error_types ()) {
+                               var error_types = new ArrayList<DataType> ();
+                               get_error_types (error_types);
+                               foreach (DataType error_type in error_types) {
                                        if (!(error_type is ErrorType)) {
                                                continue;
                                        }
@@ -1105,7 +1148,7 @@ public class Vala.Method : Subroutine, Callable {
        }
 
        public bool has_error_type_parameter () {
-               if (get_error_types ().size > 0) {
+               if (tree_can_fail) {
                        return true;
                }
                if (base_method != null && base_method != this && base_method.has_error_type_parameter ()) {
diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala
index 1ff013b..3878db0 100644
--- a/vala/valamethodcall.vala
+++ b/vala/valamethodcall.vala
@@ -142,6 +142,27 @@ public class Vala.MethodCall : Expression {
                return call.is_accessible (sym);
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               if (source_reference == null) {
+                       source_reference = this.source_reference;
+               }
+               var mtype = call.value_type;
+               if (mtype is MethodType) {
+                       var m = ((MethodType) mtype).method_symbol;
+                       if (!(m != null && m.coroutine && !is_yield_expression && ((MemberAccess) 
call).member_name != "end")) {
+                               m.get_error_types (collection, source_reference);
+                       }
+               } else if (mtype is ObjectType) {
+                       // constructor
+                       var cl = (Class) ((ObjectType) mtype).type_symbol;
+                       var m = cl.default_construction_method;
+                       m.get_error_types (collection, source_reference);
+               } else if (mtype is DelegateType) {
+                       var d = ((DelegateType) mtype).delegate_symbol;
+                       d.get_error_types (collection, source_reference);
+               }
+       }
+
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
@@ -471,8 +492,6 @@ public class Vala.MethodCall : Expression {
                formal_value_type = ret_type.copy ();
                value_type = formal_value_type.get_actual_type (target_object_type, method_type_args, this);
 
-               bool may_throw = false;
-
                if (mtype is MethodType) {
                        var m = ((MethodType) mtype).method_symbol;
                        if (is_yield_expression) {
@@ -486,19 +505,7 @@ public class Vala.MethodCall : Expression {
                                        Report.error (source_reference, "yield expression not available 
outside async method");
                                }
                        }
-                       if (m != null && m.coroutine && !is_yield_expression && ((MemberAccess) 
call).member_name != "end") {
-                               // .begin call of async method, no error can happen here
-                       } else {
-                               foreach (DataType error_type in m.get_error_types ()) {
-                                       may_throw = true;
 
-                                       // ensure we can trace back which expression may throw errors of this 
type
-                                       var call_error_type = error_type.copy ();
-                                       call_error_type.source_reference = source_reference;
-
-                                       add_error_type (call_error_type);
-                               }
-                       }
                        if (m.returns_floating_reference) {
                                value_type.floating_reference = true;
                        }
@@ -586,30 +593,6 @@ public class Vala.MethodCall : Expression {
                                        mtype = new MethodType (m.get_end_method ());
                                }
                        }
-               } else if (mtype is ObjectType) {
-                       // constructor
-                       var cl = (Class) ((ObjectType) mtype).type_symbol;
-                       var m = cl.default_construction_method;
-                       foreach (DataType error_type in m.get_error_types ()) {
-                               may_throw = true;
-
-                               // ensure we can trace back which expression may throw errors of this type
-                               var call_error_type = error_type.copy ();
-                               call_error_type.source_reference = source_reference;
-
-                               add_error_type (call_error_type);
-                       }
-               } else if (mtype is DelegateType) {
-                       var d = ((DelegateType) mtype).delegate_symbol;
-                       foreach (DataType error_type in d.get_error_types ()) {
-                               may_throw = true;
-
-                               // ensure we can trace back which expression may throw errors of this type
-                               var call_error_type = error_type.copy ();
-                               call_error_type.source_reference = source_reference;
-
-                               add_error_type (call_error_type);
-                       }
                }
 
                if (!context.analyzer.check_arguments (this, mtype, params, get_argument_list ())) {
@@ -625,7 +608,7 @@ public class Vala.MethodCall : Expression {
                        }
                }
 
-               if (may_throw) {
+               if (tree_can_fail) {
                        if (parent_node is LocalVariable || parent_node is ExpressionStatement) {
                                // simple statements, no side effects after method call
                        } else if (!(context.analyzer.get_current_symbol (this) is Block)) {
diff --git a/vala/valaobjectcreationexpression.vala b/vala/valaobjectcreationexpression.vala
index e9038bf..7b7250d 100644
--- a/vala/valaobjectcreationexpression.vala
+++ b/vala/valaobjectcreationexpression.vala
@@ -253,8 +253,6 @@ public class Vala.ObjectCreationExpression : Expression {
                value_type = type_reference.copy ();
                value_type.value_owned = true;
 
-               bool may_throw = false;
-
                int given_num_type_args = type_reference.get_type_arguments ().size;
                int expected_num_type_args = 0;
 
@@ -431,16 +429,6 @@ public class Vala.ObjectCreationExpression : Expression {
                        }
 
                        context.analyzer.check_arguments (this, new MethodType (m), m.get_parameters (), 
args);
-
-                       foreach (DataType error_type in m.get_error_types ()) {
-                               may_throw = true;
-
-                               // ensure we can trace back which expression may throw errors of this type
-                               var call_error_type = error_type.copy ();
-                               call_error_type.source_reference = source_reference;
-
-                               add_error_type (call_error_type);
-                       }
                } else if (type_reference is ErrorType) {
                        if (type_reference != null) {
                                type_reference.check (context);
@@ -492,7 +480,7 @@ public class Vala.ObjectCreationExpression : Expression {
                        context.analyzer.visit_member_initializer (init, type_reference);
                }
 
-               if (may_throw) {
+               if (tree_can_fail) {
                        if (parent_node is LocalVariable || parent_node is ExpressionStatement) {
                                // simple statements, no side effects after method call
                        } else if (!(context.analyzer.get_current_symbol (this) is Block)) {
@@ -527,6 +515,16 @@ public class Vala.ObjectCreationExpression : Expression {
                return !error;
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               if (symbol_reference is Method) {
+                       if (source_reference == null) {
+                               source_reference = this.source_reference;
+                       }
+                       var m = (Method) symbol_reference;
+                       m.get_error_types (collection, source_reference);
+               }
+       }
+
        public override void emit (CodeGenerator codegen) {
                foreach (Expression arg in argument_list) {
                        arg.emit (codegen);
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 127a118..bea5d20 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -332,7 +332,7 @@ public class Vala.Parser : CodeVisitor {
 
                index = -1;
                size = 0;
-
+               
                next ();
 
 
@@ -348,7 +348,7 @@ public class Vala.Parser : CodeVisitor {
                } catch (ParseError e) {
                        report_parse_error (e);
                }
-
+               
                scanner = null;
                if (!has_global_context) {
                        context = null;
@@ -406,7 +406,7 @@ public class Vala.Parser : CodeVisitor {
                        }
                        accept (TokenType.INTERR);
                }
-
+               
                while (accept (TokenType.OPEN_BRACKET)) {
                        do {
                                // required for decision between expression and declaration statement
@@ -423,12 +423,12 @@ public class Vala.Parser : CodeVisitor {
 
        bool is_inner_array_type () {
                var begin = get_location ();
-
+               
                var result = accept (TokenType.OPEN_PARENS) && accept (TokenType.UNOWNED) && current() != 
TokenType.CLOSE_PARENS;
                rollback (begin);
                return result;
        }
-
+       
        DataType parse_type (bool owned_by_default, bool can_weak_ref, bool require_unowned = false) throws 
ParseError {
                var begin = get_location ();
 
@@ -468,7 +468,7 @@ public class Vala.Parser : CodeVisitor {
                if (accept (TokenType.OPEN_PARENS)) {
                        type = parse_type (false, false, true);
                        expect (TokenType.CLOSE_PARENS);
-
+                       
                        inner_type_owned = false;
 
                        expect (TokenType.OPEN_BRACKET);
@@ -479,7 +479,7 @@ public class Vala.Parser : CodeVisitor {
                        } else {
                                var sym = parse_symbol_name ();
                                List<DataType> type_arg_list = parse_type_argument_list (false);
-
+                               
                                type = new UnresolvedType.from_symbol (sym, get_src (begin));
                                if (type_arg_list != null) {
                                        foreach (DataType type_arg in type_arg_list) {
@@ -487,7 +487,7 @@ public class Vala.Parser : CodeVisitor {
                                        }
                                }
                        }
-
+                       
                        while (accept (TokenType.STAR)) {
                                type = new PointerType (type, get_src (begin));
                        }
@@ -496,7 +496,7 @@ public class Vala.Parser : CodeVisitor {
                                type.nullable = accept (TokenType.INTERR);
                        }
                }
-
+                       
                // array brackets in types are read from right to left,
                // this is more logical, especially when nullable arrays
                // or pointers are involved
@@ -914,7 +914,7 @@ public class Vala.Parser : CodeVisitor {
                        expect (TokenType.OPEN_PARENS);
                        expect (TokenType.UNOWNED);
                }
-
+               
                var member = parse_member_name ();
                DataType element_type = UnresolvedType.new_from_expression (member);
                bool is_pointer_type = false;
@@ -927,14 +927,14 @@ public class Vala.Parser : CodeVisitor {
                                element_type.nullable = true;
                        }
                }
-
+               
                if (inner_array_type) {
                        expect (TokenType.CLOSE_PARENS);
                        element_type.value_owned = false;
                } else {
                        element_type.value_owned = true;
                }
-
+               
                expect (TokenType.OPEN_BRACKET);
 
                bool size_specified = false;
@@ -1624,7 +1624,7 @@ public class Vala.Parser : CodeVisitor {
                if (current () == TokenType.OPEN_PARENS) {
                        return !is_inner_array_type ();
                }
-
+               
                var begin = get_location ();
 
                // decide between declaration and expression statement
@@ -2231,17 +2231,17 @@ public class Vala.Parser : CodeVisitor {
        void parse_declaration (Symbol parent, bool root = false) throws ParseError {
                comment = scanner.pop_comment ();
                var attrs = parse_attributes ();
-
+               
                var begin = get_location ();
-
+               
                TokenType last_keyword = current ();
-
+               
                while (is_declaration_keyword (current ())) {
                        last_keyword = current ();
                        next ();
                }
-
-               switch (current ()) {
+       
+               switch (current ()) {   
                case TokenType.CONSTRUCT:
                        rollback (begin);
                        parse_constructor_declaration (parent, attrs);
@@ -2808,7 +2808,7 @@ public class Vala.Parser : CodeVisitor {
 
                if (accept (TokenType.THROWS)) {
                        do {
-                               prop.add_error_type (parse_type (true, false));
+                               parse_type (true, false);
                        } while (accept (TokenType.COMMA));
                        Report.error (prop.source_reference, "properties throwing errors are not supported 
yet");
                }
diff --git a/vala/valapointerindirection.vala b/vala/valapointerindirection.vala
index 97f6473..0fad599 100644
--- a/vala/valapointerindirection.vala
+++ b/vala/valapointerindirection.vala
@@ -37,7 +37,7 @@ public class Vala.PointerIndirection : Expression {
                        _inner.parent_node = this;
                }
        }
-
+       
        private Expression _inner;
 
        /**
@@ -50,7 +50,7 @@ public class Vala.PointerIndirection : Expression {
                this.source_reference = source_reference;
                this.inner = inner;
        }
-
+       
        public override void accept (CodeVisitor visitor) {
                inner.accept (visitor);
 
@@ -73,6 +73,10 @@ public class Vala.PointerIndirection : Expression {
                return inner.is_accessible (sym);
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               inner.get_error_types (collection, source_reference);
+       }
+
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
diff --git a/vala/valapropertyaccessor.vala b/vala/valapropertyaccessor.vala
index ccc1be5..bcc6221 100644
--- a/vala/valapropertyaccessor.vala
+++ b/vala/valapropertyaccessor.vala
@@ -187,7 +187,9 @@ public class Vala.PropertyAccessor : Subroutine {
 
                        body.check (context);
 
-                       foreach (DataType body_error_type in body.get_error_types ()) {
+                       var error_types = new ArrayList<DataType> ();
+                       body.get_error_types (error_types);
+                       foreach (DataType body_error_type in 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()));
                                }
diff --git a/vala/valareturnstatement.vala b/vala/valareturnstatement.vala
index 9cc8017..99e7e61 100644
--- a/vala/valareturnstatement.vala
+++ b/vala/valareturnstatement.vala
@@ -70,6 +70,12 @@ public class Vala.ReturnStatement : CodeNode, Statement {
                }
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               if (return_expression != null) {
+                       return_expression.get_error_types (collection, source_reference);
+               }
+       }
+
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
@@ -140,8 +146,6 @@ public class Vala.ReturnStatement : CodeNode, Statement {
                        Report.warning (source_reference, "`null' incompatible with return type `%s`".printf 
(current_return_type.to_string ()));
                }
 
-               add_error_types (return_expression.get_error_types ());
-
                return !error;
        }
 
diff --git a/vala/valastatementlist.vala b/vala/valastatementlist.vala
index 934227a..5159598 100644
--- a/vala/valastatementlist.vala
+++ b/vala/valastatementlist.vala
@@ -48,6 +48,12 @@ public class Vala.StatementList : CodeNode, Statement {
                list.insert (index, stmt);
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               foreach (var stmt in list) {
+                       stmt.get_error_types (collection, source_reference);
+               }
+       }
+
        public override void accept (CodeVisitor visitor) {
                foreach (Statement stmt in list) {
                        stmt.accept (visitor);
diff --git a/vala/valaswitchsection.vala b/vala/valaswitchsection.vala
index 0e8395d..8cc177a 100644
--- a/vala/valaswitchsection.vala
+++ b/vala/valaswitchsection.vala
@@ -85,6 +85,13 @@ public class Vala.SwitchSection : Block {
                }
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               // use get_statements () instead of statement_list to not miss errors within StatementList 
objects
+               foreach (var stmt in get_statements ()) {
+                       stmt.get_error_types (collection, source_reference);
+               }
+       }
+
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
@@ -106,11 +113,6 @@ public class Vala.SwitchSection : Block {
                        local.active = false;
                }
 
-               // use get_statements () instead of statement_list to not miss errors within StatementList 
objects
-               foreach (Statement stmt in get_statements ()) {
-                       add_error_types (stmt.get_error_types ());
-               }
-
                return !error;
        }
 
diff --git a/vala/valaswitchstatement.vala b/vala/valaswitchstatement.vala
index 66dab01..d6d2999 100644
--- a/vala/valaswitchstatement.vala
+++ b/vala/valaswitchstatement.vala
@@ -53,7 +53,7 @@ public class Vala.SwitchStatement : CodeNode, Statement {
                this.source_reference = source_reference;
                this.expression = expression;
        }
-
+       
        /**
         * Appends the specified section to the list of switch sections.
         *
@@ -63,7 +63,7 @@ public class Vala.SwitchStatement : CodeNode, Statement {
                section.parent_node = this;
                sections.add (section);
        }
-
+       
        /**
         * Returns a copy of the list of switch sections.
         *
@@ -81,7 +81,7 @@ public class Vala.SwitchStatement : CodeNode, Statement {
                expression.accept (visitor);
 
                visitor.visit_end_full_expression (expression);
-
+               
                foreach (SwitchSection section in sections) {
                        section.accept (visitor);
                }
@@ -93,6 +93,12 @@ public class Vala.SwitchStatement : CodeNode, Statement {
                }
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               foreach (SwitchSection section in sections) {
+                       section.get_error_types (collection, source_reference);
+               }
+       }
+       
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
@@ -140,7 +146,6 @@ public class Vala.SwitchStatement : CodeNode, Statement {
                                        }
                                }
                        }
-                       add_error_types (section.get_error_types ());
                }
 
                return !error;
diff --git a/vala/valathrowstatement.vala b/vala/valathrowstatement.vala
index 0c30d33..2c5128c 100644
--- a/vala/valathrowstatement.vala
+++ b/vala/valathrowstatement.vala
@@ -72,6 +72,15 @@ public class Vala.ThrowStatement : CodeNode, Statement {
                }
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               if (source_reference == null) {
+                       source_reference = this.source_reference;
+               }
+               var error_type = error_expression.value_type.copy ();
+               error_type.source_reference = source_reference;
+               collection.add (error_type);
+       }
+
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
@@ -101,11 +110,6 @@ public class Vala.ThrowStatement : CodeNode, Statement {
                        }
                }
 
-               var error_type = error_expression.value_type.copy ();
-               error_type.source_reference = source_reference;
-
-               add_error_type (error_type);
-
                return !error;
        }
 
diff --git a/vala/valatrystatement.vala b/vala/valatrystatement.vala
index 38000f5..3ae8924 100644
--- a/vala/valatrystatement.vala
+++ b/vala/valatrystatement.vala
@@ -104,6 +104,31 @@ public class Vala.TryStatement : CodeNode, Statement {
                }
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               var error_types = new ArrayList<DataType> ();
+               body.get_error_types (error_types, source_reference);
+
+               foreach (CatchClause clause in catch_clauses) {
+                       for (int i=0; i < error_types.size; i++) {
+                               var error_type = error_types[i];
+                               if (clause.error_type == null || error_type.compatible (clause.error_type)) {
+                                       error_types.remove_at (i);
+                                       i--;
+                               }
+                       }
+
+                       clause.body.get_error_types (collection, source_reference);
+               }
+
+               if (finally_body != null) {
+                       finally_body.get_error_types (collection, source_reference);
+               }
+
+               foreach (var error_type in error_types) {
+                       collection.add (error_type);
+               }
+       }
+
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
@@ -113,38 +138,14 @@ public class Vala.TryStatement : CodeNode, Statement {
 
                body.check (context);
 
-               var error_types = new ArrayList<DataType> ();
-               foreach (DataType body_error_type in body.get_error_types ()) {
-                       error_types.add (body_error_type);
-               }
-
-               var handled_error_types = new ArrayList<DataType> ();
                foreach (CatchClause clause in catch_clauses) {
-                       foreach (DataType body_error_type in error_types) {
-                               if (clause.error_type == null || body_error_type.compatible 
(clause.error_type)) {
-                                       handled_error_types.add (body_error_type);
-                               }
-                       }
-                       foreach (DataType handled_error_type in handled_error_types) {
-                               error_types.remove (handled_error_type);
-                       }
-                       handled_error_types.clear ();
-
                        clause.check (context);
-                       foreach (DataType body_error_type in clause.body.get_error_types ()) {
-                               error_types.add (body_error_type);
-                       }
                }
 
                if (finally_body != null) {
                        finally_body.check (context);
-                       foreach (DataType body_error_type in finally_body.get_error_types ()) {
-                               error_types.add (body_error_type);
-                       }
                }
 
-               add_error_types (error_types);
-
                return !error;
        }
 
diff --git a/vala/valaunaryexpression.vala b/vala/valaunaryexpression.vala
index 87f4032..f98a5d0 100644
--- a/vala/valaunaryexpression.vala
+++ b/vala/valaunaryexpression.vala
@@ -44,7 +44,7 @@ public class Vala.UnaryExpression : Expression {
                        _inner.parent_node = this;
                }
        }
-
+       
        private Expression _inner;
 
        /**
@@ -150,6 +150,10 @@ public class Vala.UnaryExpression : Expression {
                return null;
        }
 
+       public override void get_error_types (Collection<DataType> collection, SourceReference? 
source_reference = null) {
+               inner.get_error_types (collection, source_reference);
+       }
+
        public override bool check (CodeContext context) {
                if (checked) {
                        return !error;
diff --git a/valadoc/symbolresolver.vala b/valadoc/symbolresolver.vala
index 4980e88..49f26b0 100644
--- a/valadoc/symbolresolver.vala
+++ b/valadoc/symbolresolver.vala
@@ -37,8 +37,10 @@ public class Valadoc.Drivers.SymbolResolver : Visitor {
                return symbol_map.get (symbol);
        }
 
-       private void resolve_thrown_list (Symbol symbol, Vala.List<Vala.DataType> types) {
-               foreach (Vala.DataType type in types) {
+       private void resolve_thrown_list (Symbol symbol, Vala.Symbol vala_symbol) {
+               var error_types = new Vala.ArrayList<Vala.DataType> ();
+               vala_symbol.get_error_types (error_types);
+               foreach (Vala.DataType type in error_types) {
                        Vala.ErrorDomain vala_edom = (Vala.ErrorDomain) type.data_type;
                        Symbol? edom = symbol_map.get (vala_edom);
                        symbol.add_child (edom ?? glib_error);
@@ -186,7 +188,7 @@ public class Valadoc.Drivers.SymbolResolver : Visitor {
                }
 
                resolve_type_reference (item.property_type);
-
+               
                item.accept_all_children (this, false);
        }
 
@@ -216,7 +218,7 @@ public class Valadoc.Drivers.SymbolResolver : Visitor {
 
                resolve_type_reference (item.return_type);
 
-               resolve_thrown_list (item, vala_delegate.get_error_types ());
+               resolve_thrown_list (item, vala_delegate);
 
                item.accept_all_children (this, false);
        }
@@ -248,7 +250,7 @@ public class Valadoc.Drivers.SymbolResolver : Visitor {
                        item.base_method = (Method?) resolve (base_vala_method);
                }
 
-               resolve_thrown_list (item, vala_method.get_error_types ());
+               resolve_thrown_list (item, vala_method);
 
                resolve_type_reference (item.return_type);
 
diff --git a/vapigen/valagidlparser.vala b/vapigen/valagidlparser.vala
index bb3c4bb..a828fdd 100644
--- a/vapigen/valagidlparser.vala
+++ b/vapigen/valagidlparser.vala
@@ -1817,8 +1817,10 @@ public class Vala.GIdlParser : CodeVisitor {
                                                        m.add_parameter (async_param);
                                                }
                                        }
-                                       foreach (DataType error_type in finish_method.get_error_types ()) {
-                                               m.add_error_type (error_type.copy ());
+                                       var error_types = new ArrayList<DataType> ();
+                                       finish_method.get_error_types (error_types, m.source_reference);
+                                       foreach (DataType error_type in error_types) {
+                                               m.add_error_type (error_type);
                                        }
                                        finish_methods.add (finish_method);
                                }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]