From 800059da901c1244a0bbefbc0f537371ea57815d Mon Sep 17 00:00:00 2001 From: Juerg Billeter Date: Sun, 13 Apr 2008 20:20:54 +0000 Subject: [PATCH] fix method compatibility checks, based on patch by Andreas Brauchli, fixes 2008-04-13 Juerg Billeter * vala/valamethod.vala, vala/valasemanticanalyzer.vala: fix method compatibility checks, based on patch by Andreas Brauchli, fixes bug 527751 svn path=/trunk/; revision=1217 --- ChangeLog | 6 ++++++ vala/valamethod.vala | 47 ++++++++++++++++++++++++++---------------- vala/valasemanticanalyzer.vala | 10 +++++---- 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index d493ed9..9744bc7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2008-04-13 Jürg Billeter + * vala/valamethod.vala, vala/valasemanticanalyzer.vala: + fix method compatibility checks, + based on patch by Andreas Brauchli, fixes bug 527751 + +2008-04-13 Jürg Billeter + * vapi/glib-2.0.vapi: add GDatalist bindings, patch by Marc-Andre Lureau, fixes bug 527243 diff --git a/vala/valamethod.vala b/vala/valamethod.vala index a108aa0..1a33bf6 100644 --- a/vala/valamethod.vala +++ b/vala/valamethod.vala @@ -379,44 +379,55 @@ public class Vala.Method : Member { } } } - + /** - * Checks whether the arguments and return type of the specified method - * matches this method. + * Checks whether the parameters and return type of this method are + * compatible with the specified method * - * @param m a method - * @return true if the specified method is compatible to this method + * @param base_method a method + * @param invalid_match error string about which check failed + * @return true if the specified method is compatible to this method */ - public bool equals (Method m2) { - if (!m2.return_type.equals (return_type)) { + public bool compatible (Method base_method, out string? invalid_match) { + if (!return_type.equals (base_method.return_type)) { + invalid_match = "incompatible return type"; return false; } - Iterator method_params_it = m2.get_parameters ().iterator (); - foreach (FormalParameter param in parameters) { - /* method may not expect less arguments */ + Iterator method_params_it = parameters.iterator (); + int param_index = 1; + foreach (FormalParameter base_param in base_method.parameters) { + /* this method may not expect less arguments */ if (!method_params_it.next ()) { + invalid_match = "too few parameters"; return false; } - if (!method_params_it.get ().type_reference.equals (param.type_reference)) { + if (!base_param.type_reference.equals (method_params_it.get ().type_reference)) { + invalid_match = "incompatible type of parameter %d".printf (param_index); return false; } + param_index++; } - /* method may not expect more arguments */ + /* this method may not expect more arguments */ if (method_params_it.next ()) { + invalid_match = "too many parameters"; return false; } - Iterator method_error_domains_it = m2.get_error_domains ().iterator (); - foreach (DataType error_domain in error_domains) { - /* method may not have less error domains */ - if (!method_error_domains_it.next ()) { - return false; + /* this method may throw more but not less errors than the base method */ + foreach (DataType method_error_domain in error_domains) { + bool match = false; + foreach (DataType base_method_error_domain in base_method.error_domains) { + if (method_error_domain.compatible (base_method_error_domain)) { + match = true; + break; + } } - if (!method_error_domains_it.get ().equals (error_domain)) { + if (!match) { + invalid_match = "incompatible error domain `%s'".printf (method_error_domain.to_string ()); return false; } } diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 2dc5330..ecebf76 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -458,9 +458,10 @@ public class Vala.SemanticAnalyzer : CodeVisitor { if (sym is Method) { var base_method = (Method) sym; if (base_method.is_abstract || base_method.is_virtual) { - if (!m.equals (base_method)) { + string invalid_match; + if (!m.compatible (base_method, out invalid_match)) { m.error = true; - Report.error (m.source_reference, "Return type and/or parameters of overriding method `%s' do not match overridden method `%s'.".printf (m.get_full_name (), base_method.get_full_name ())); + Report.error (m.source_reference, "overriding method `%s' is incompatible with base method `%s': %s.".printf (m.get_full_name (), base_method.get_full_name (), invalid_match)); return; } @@ -482,9 +483,10 @@ public class Vala.SemanticAnalyzer : CodeVisitor { if (sym is Method) { var base_method = (Method) sym; if (base_method.is_abstract) { - if (!m.equals (base_method)) { + string invalid_match; + if (!m.compatible (base_method, out invalid_match)) { m.error = true; - Report.error (m.source_reference, "Return type and/or parameters of overriding method `%s' do not match overridden method `%s'.".printf (m.get_full_name (), base_method.get_full_name ())); + Report.error (m.source_reference, "overriding method `%s' is incompatible with base method `%s': %s.".printf (m.get_full_name (), base_method.get_full_name (), invalid_match)); return; } -- 2.7.4